<!DOCTYPE html>
<html lang="en">
    <head hexo-theme='https://github.com/volantis-x/hexo-theme-volantis/#5.8.0'>
  <meta name="generator" content="Hexo 7.0.0">
  <meta name="Volantis" content="5.8.0">
  <meta charset="utf-8">
  <!-- SEO相关 -->
  
  <link rel="canonical" href="http://example.com/2023/12/22/javascript/"/>
  <!-- 渲染优化 -->
    <meta http-equiv='x-dns-prefetch-control' content='on' />
      <link rel='dns-prefetch' href='https://unpkg.com'>
      <link rel="preconnect" href="https://unpkg.com" crossorigin>
  <meta name="renderer" content="webkit">
  <meta name="force-rendering" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta http-equiv="Content-Security-Policy" content=" default-src 'self' https:; block-all-mixed-content; base-uri 'self' https:; form-action 'self' https:; worker-src 'self' https:; connect-src 'self' https: *; img-src 'self' data: https: *; media-src 'self' https: *; font-src 'self' data: https: *; frame-src 'self' https: *; manifest-src 'self' https: *; child-src https:; script-src 'self' https: 'unsafe-inline' *; style-src 'self' https: 'unsafe-inline' *; ">
  <meta name="HandheldFriendly" content="True" >
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
  <meta content="black-translucent" name="apple-mobile-web-app-status-bar-style">
  <meta content="telephone=no" name="format-detection">
  <!-- import head_begin begin -->
  <!-- import head_begin end -->
  <!-- Custom Files headBegin begin-->
  
  <!-- Custom Files headBegin end-->
  <!-- front-matter head_begin begin -->
  <!-- front-matter head_begin end -->
  <link rel="preload" href="/css/style.css" as="style">
  <link rel="preload" href="https://unpkg.com/volantis-static@0.0.1654736714924/media/fonts/VarelaRound/VarelaRound-Regular.ttf" as="font" type="font/ttf" crossorigin="anonymous">
<link rel="preload" href="https://unpkg.com/volantis-static@0.0.1654736714924/media/fonts/UbuntuMono/UbuntuMono-Regular.ttf" as="font" type="font/ttf" crossorigin="anonymous">

  <!-- feed -->
  <!-- 页面元数据 -->
  <title>JavaScript - Knowledge</title>
  <meta name="keywords" content="JavaScript,html css node vue node">
  <meta desc name="description" content="html css node vue node - weijt - Knowledge">
  
<meta property="og:type" content="article">
<meta property="og:title" content="JavaScript">
<meta property="og:url" content="http://example.com/2023/12/22/JavaScript/index.html">
<meta property="og:site_name" content="Knowledge">
<meta property="og:description" content="localStorage1234567891011121314&#x2F;&#x2F; 数据存在 localStorage里面可以长期保留，也就是说关闭页面后，存储在 localStorage 的数据还在，不会丢失。&#x2F;&#x2F; 不同的浏览器里localStorage 的存储大小不一样，比如有些大小是4M&#x2F;&#x2F; 方法：&#x2F;&#x2F; 1：访问本地storage对象，通过setItem（）输入键名和值建立了一个数据项&#x2F;&#x2F; localSto">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png">
<meta property="article:published_time" content="2023-12-22T03:11:03.467Z">
<meta property="article:modified_time" content="2024-06-13T01:38:57.695Z">
<meta property="article:author" content="weijt">
<meta property="article:tag" content="JavaScript">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png">
  <style>
    /* 首屏样式 */
    #safearea {
  display: none;
}
:root {
  --color-site-body: #f4f4f4;
  --color-site-bg: #f4f4f4;
  --color-site-inner: #fff;
  --color-site-footer: #666;
  --color-card: #fff;
  --color-text: #444;
  --color-block: #f6f6f6;
  --color-inlinecode: #c74f00;
  --color-codeblock: #fff7ea;
  --color-h1: #3a3a3a;
  --color-h2: #3a3a3a;
  --color-h3: #333;
  --color-h4: #444;
  --color-h5: #555;
  --color-h6: #666;
  --color-p: #444;
  --color-list: #666;
  --color-list-hl: #30ad91;
  --color-meta: #888;
  --color-read-bkg: #e0d8c8;
  --color-read-post: #f8f1e2;
  --color-copyright-bkg: #f5f5f5;
}
* {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  outline: none;
  margin: 0;
  padding: 0;
}
*::-webkit-scrollbar {
  height: 4px;
  width: 4px;
}
*::-webkit-scrollbar-track-piece {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: #3dd9b6;
  cursor: pointer;
  border-radius: 2px;
  -webkit-border-radius: 2px;
}
*::-webkit-scrollbar-thumb:hover {
  background: #ff5722;
}
html {
  color: var(--color-text);
  width: 100%;
  height: 100%;
  font-family: UbuntuMono, "Varela Round", "PingFang SC", "Microsoft YaHei", Helvetica, Arial, Menlo, Monaco, monospace, sans-serif;
  font-size: 16px;
}
html >::-webkit-scrollbar {
  height: 4px;
  width: 4px;
}
html >::-webkit-scrollbar-track-piece {
  background: transparent;
}
html >::-webkit-scrollbar-thumb {
  background: #54b5a0 linear-gradient(45deg, rgba(255,255,255,0.4) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.4) 50%, rgba(255,255,255,0.4) 75%, transparent 75%, transparent);
  cursor: pointer;
  border-radius: 2px;
  -webkit-border-radius: 2px;
}
html >::-webkit-scrollbar-thumb:hover {
  background: #54b5a0 linear-gradient(45deg, rgba(255,255,255,0.4) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.4) 50%, rgba(255,255,255,0.4) 75%, transparent 75%, transparent);
}
body {
  background-color: var(--color-site-body);
  text-rendering: optimizelegibility;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
}
body.modal-active {
  overflow: hidden;
}
@media screen and (max-width: 680px) {
  body.modal-active {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
  }
}
a {
  color: #2092ec;
  cursor: pointer;
  text-decoration: none;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
a:hover {
  color: #ff5722;
}
a:active,
a:hover {
  outline: 0;
}
ul,
ol {
  padding-left: 0;
}
ul li,
ol li {
  list-style: none;
}
header {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
}
img {
  border: 0;
  background: none;
  max-width: 100%;
}
svg:not(:root) {
  overflow: hidden;
}
hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  height: 0;
  border: 0;
  border-radius: 1px;
  -webkit-border-radius: 1px;
  border-bottom: 1px solid rgba(68,68,68,0.1);
}
button,
input {
  color: inherit;
  font: inherit;
  margin: 0;
}
button {
  overflow: visible;
  text-transform: none;
  -webkit-appearance: button;
  cursor: pointer;
}
@supports (backdrop-filter: blur(20px)) {
  .blur {
    background: rgba(255,255,255,0.9) !important;
    backdrop-filter: saturate(200%) blur(20px);
  }
}
.shadow {
  box-shadow: 0 1px 2px 0px rgba(0,0,0,0.1);
  -webkit-box-shadow: 0 1px 2px 0px rgba(0,0,0,0.1);
}
.shadow.floatable {
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
.shadow.floatable:hover {
  box-shadow: 0 2px 4px 0px rgba(0,0,0,0.1), 0 4px 8px 0px rgba(0,0,0,0.1), 0 8px 16px 0px rgba(0,0,0,0.1);
  -webkit-box-shadow: 0 2px 4px 0px rgba(0,0,0,0.1), 0 4px 8px 0px rgba(0,0,0,0.1), 0 8px 16px 0px rgba(0,0,0,0.1);
}
#l_cover {
  min-height: 64px;
}
.cover-wrapper {
  top: 0;
  left: 0;
  max-width: 100%;
  height: 100vh;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  flex-wrap: nowrap;
  -webkit-flex-wrap: nowrap;
  -khtml-flex-wrap: nowrap;
  -moz-flex-wrap: nowrap;
  -o-flex-wrap: nowrap;
  -ms-flex-wrap: nowrap;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  align-items: center;
  align-self: center;
  align-content: center;
  color: var(--color-site-inner);
  padding: 0 16px;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  position: relative;
  overflow: hidden;
  margin-bottom: -100px;
}
.cover-wrapper .cover-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: cover;
  -webkit-background-size: cover;
  -moz-background-size: cover;
}
.cover-wrapper .cover-bg.lazyload:not(.loaded) {
  opacity: 0;
  -webkit-opacity: 0;
  -moz-opacity: 0;
}
.cover-wrapper .cover-bg.lazyload.loaded {
  animation-delay: 0s;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
  animation-timing-function: ease-out;
  animation-name: fadeIn;
}
@-moz-keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
    filter: blur(12px);
    transform: scale(1.02);
    -webkit-transform: scale(1.02);
    -khtml-transform: scale(1.02);
    -moz-transform: scale(1.02);
    -o-transform: scale(1.02);
    -ms-transform: scale(1.02);
  }
  100% {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@-webkit-keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
    filter: blur(12px);
    transform: scale(1.02);
    -webkit-transform: scale(1.02);
    -khtml-transform: scale(1.02);
    -moz-transform: scale(1.02);
    -o-transform: scale(1.02);
    -ms-transform: scale(1.02);
  }
  100% {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@-o-keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
    filter: blur(12px);
    transform: scale(1.02);
    -webkit-transform: scale(1.02);
    -khtml-transform: scale(1.02);
    -moz-transform: scale(1.02);
    -o-transform: scale(1.02);
    -ms-transform: scale(1.02);
  }
  100% {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@keyframes fadeIn {
  0% {
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
    filter: blur(12px);
    transform: scale(1.02);
    -webkit-transform: scale(1.02);
    -khtml-transform: scale(1.02);
    -moz-transform: scale(1.02);
    -o-transform: scale(1.02);
    -ms-transform: scale(1.02);
  }
  100% {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
.cover-wrapper .cover-body {
  z-index: 1;
  position: relative;
  width: 100%;
  height: 100%;
}
.cover-wrapper#full {
  height: calc(100vh + 100px);
  padding-bottom: 100px;
}
.cover-wrapper#half {
  max-height: 640px;
  min-height: 400px;
  height: calc(36vh - 64px + 200px);
}
.cover-wrapper #scroll-down {
  width: 100%;
  height: 64px;
  position: absolute;
  bottom: 100px;
  text-align: center;
  cursor: pointer;
}
.cover-wrapper #scroll-down .scroll-down-effects {
  color: #fff;
  font-size: 24px;
  line-height: 64px;
  position: absolute;
  width: 24px;
  left: calc(50% - 12px);
  text-shadow: 0 1px 2px rgba(0,0,0,0.1);
  animation: scroll-down-effect 1.5s infinite;
  -webkit-animation: scroll-down-effect 1.5s infinite;
  -khtml-animation: scroll-down-effect 1.5s infinite;
  -moz-animation: scroll-down-effect 1.5s infinite;
  -o-animation: scroll-down-effect 1.5s infinite;
  -ms-animation: scroll-down-effect 1.5s infinite;
}
@-moz-keyframes scroll-down-effect {
  0% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
  50% {
    top: -16px;
    opacity: 0.4;
    -webkit-opacity: 0.4;
    -moz-opacity: 0.4;
  }
  100% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@-webkit-keyframes scroll-down-effect {
  0% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
  50% {
    top: -16px;
    opacity: 0.4;
    -webkit-opacity: 0.4;
    -moz-opacity: 0.4;
  }
  100% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@-o-keyframes scroll-down-effect {
  0% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
  50% {
    top: -16px;
    opacity: 0.4;
    -webkit-opacity: 0.4;
    -moz-opacity: 0.4;
  }
  100% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@keyframes scroll-down-effect {
  0% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
  50% {
    top: -16px;
    opacity: 0.4;
    -webkit-opacity: 0.4;
    -moz-opacity: 0.4;
  }
  100% {
    top: 0;
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
.cover-wrapper .cover-body {
  margin-top: 64px;
  margin-bottom: 100px;
}
.cover-wrapper .cover-body,
.cover-wrapper .cover-body .top,
.cover-wrapper .cover-body .bottom {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  -webkit-justify-content: center;
  -khtml-justify-content: center;
  -moz-justify-content: center;
  -o-justify-content: center;
  -ms-justify-content: center;
  max-width: 100%;
}
.cover-wrapper .cover-body .bottom {
  margin-top: 32px;
}
.cover-wrapper .cover-body .title {
  font-family: "Varela Round", "PingFang SC", "Microsoft YaHei", Helvetica, Arial, Helvetica, monospace;
  font-size: 3.125rem;
  line-height: 1.2;
  text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.cover-wrapper .cover-body .subtitle {
  font-size: 20px;
}
.cover-wrapper .cover-body .logo {
  max-height: 120px;
  max-width: calc(100% - 4 * 16px);
}
@media screen and (min-height: 1024px) {
  .cover-wrapper .cover-body .title {
    font-size: 3rem;
  }
  .cover-wrapper .cover-body .subtitle {
    font-size: 1.05rem;
  }
  .cover-wrapper .cover-body .logo {
    max-height: 150px;
  }
}
.cover-wrapper .cover-body .m_search {
  position: relative;
  max-width: calc(100% - 16px);
  width: 320px;
  vertical-align: middle;
}
.cover-wrapper .cover-body .m_search .form {
  position: relative;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  width: 100%;
}
.cover-wrapper .cover-body .m_search .icon,
.cover-wrapper .cover-body .m_search .input {
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
.cover-wrapper .cover-body .m_search .icon {
  position: absolute;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  line-height: 2.5rem;
  width: 32px;
  top: 0;
  left: 5px;
  color: rgba(68,68,68,0.75);
}
.cover-wrapper .cover-body .m_search .input {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  height: 2.5rem;
  width: 100%;
  box-shadow: none;
  -webkit-box-shadow: none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  font-size: 0.875rem;
  -webkit-appearance: none;
  padding-left: 36px;
  border-radius: 1.4rem;
  -webkit-border-radius: 1.4rem;
  background: rgba(255,255,255,0.6);
  backdrop-filter: blur(10px);
  border: none;
  color: var(--color-text);
}
@media screen and (max-width: 500px) {
  .cover-wrapper .cover-body .m_search .input {
    padding-left: 36px;
  }
}
.cover-wrapper .cover-body .m_search .input:hover {
  background: rgba(255,255,255,0.8);
}
.cover-wrapper .cover-body .m_search .input:focus {
  background: #fff;
}
.cover-wrapper .list-h {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: horizontal;
  -moz-box-orient: horizontal;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
  flex-wrap: wrap;
  -webkit-flex-wrap: wrap;
  -khtml-flex-wrap: wrap;
  -moz-flex-wrap: wrap;
  -o-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  align-items: stretch;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.cover-wrapper .list-h a {
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  -webkit-flex: 1 0;
  -ms-flex: 1 0;
  flex: 1 0;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  font-weight: 600;
}
.cover-wrapper .list-h a img {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  border-radius: 2px;
  -webkit-border-radius: 2px;
  margin: 4px;
  min-width: 40px;
  max-width: 44px;
}
@media screen and (max-width: 768px) {
  .cover-wrapper .list-h a img {
    min-width: 36px;
    max-width: 40px;
  }
}
@media screen and (max-width: 500px) {
  .cover-wrapper .list-h a img {
    margin: 2px 4px;
    min-width: 32px;
    max-width: 36px;
  }
}
@media screen and (max-width: 375px) {
  .cover-wrapper .list-h a img {
    min-width: 28px;
    max-width: 32px;
  }
}
.cover-wrapper {
  max-width: 100%;
}
.cover-wrapper.search .bottom .menu {
  margin-top: 16px;
}
.cover-wrapper.search .bottom .menu .list-h a {
  white-space: nowrap;
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: horizontal;
  -moz-box-orient: horizontal;
  -webkit-flex-direction: row;
  -ms-flex-direction: row;
  flex-direction: row;
  align-items: baseline;
  padding: 2px;
  margin: 4px;
  color: var(--color-site-inner);
  opacity: 0.75;
  -webkit-opacity: 0.75;
  -moz-opacity: 0.75;
  text-shadow: 0 1px 2px rgba(0,0,0,0.05);
  border-bottom: 2px solid transparent;
}
.cover-wrapper.search .bottom .menu .list-h a i {
  margin-right: 4px;
}
.cover-wrapper.search .bottom .menu .list-h a p {
  font-size: 0.9375rem;
}
.cover-wrapper.search .bottom .menu .list-h a:hover,
.cover-wrapper.search .bottom .menu .list-h a.active,
.cover-wrapper.search .bottom .menu .list-h a:active {
  opacity: 1;
  -webkit-opacity: 1;
  -moz-opacity: 1;
  border-bottom: 2px solid var(--color-site-inner);
}
.cover-wrapper.dock .menu,
.cover-wrapper.featured .menu,
.cover-wrapper.focus .menu {
  border-radius: 6px;
  -webkit-border-radius: 6px;
}
.cover-wrapper.dock .menu .list-h a,
.cover-wrapper.featured .menu .list-h a,
.cover-wrapper.focus .menu .list-h a {
  -webkit-box-direction: normal;
  -moz-box-direction: normal;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  align-items: center;
  padding: 12px;
  line-height: 24px;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  border-bottom: none;
  text-align: center;
  align-content: flex-end;
  color: rgba(68,68,68,0.7);
  font-size: 1.5rem;
}
@media screen and (max-width: 500px) {
  .cover-wrapper.dock .menu .list-h a,
  .cover-wrapper.featured .menu .list-h a,
  .cover-wrapper.focus .menu .list-h a {
    padding: 12px 8px;
  }
}
.cover-wrapper.dock .menu .list-h a i,
.cover-wrapper.featured .menu .list-h a i,
.cover-wrapper.focus .menu .list-h a i {
  margin: 8px;
}
.cover-wrapper.dock .menu .list-h a p,
.cover-wrapper.featured .menu .list-h a p,
.cover-wrapper.focus .menu .list-h a p {
  font-size: 0.875rem;
}
.cover-wrapper.dock .menu .list-h a.active,
.cover-wrapper.featured .menu .list-h a.active,
.cover-wrapper.focus .menu .list-h a.active {
  background: var(--color-card);
  backdrop-filter: none;
}
.cover-wrapper.dock .menu .list-h a.active i,
.cover-wrapper.featured .menu .list-h a.active i,
.cover-wrapper.focus .menu .list-h a.active i,
.cover-wrapper.dock .menu .list-h a.active i+p,
.cover-wrapper.featured .menu .list-h a.active i+p,
.cover-wrapper.focus .menu .list-h a.active i+p {
  color: #3dd9b6;
}
.cover-wrapper.dock .menu .list-h a.active img+p,
.cover-wrapper.featured .menu .list-h a.active img+p,
.cover-wrapper.focus .menu .list-h a.active img+p {
  color: var(--color-text);
}
.cover-wrapper.dock .menu .list-h a:hover,
.cover-wrapper.featured .menu .list-h a:hover,
.cover-wrapper.focus .menu .list-h a:hover {
  background: var(--color-card);
}
.cover-wrapper.dock .top {
  margin-bottom: 48px;
}
.cover-wrapper.dock .menu {
  background: rgba(255,255,255,0.5);
  position: absolute;
  bottom: 0;
  max-width: 100%;
}
.cover-wrapper.dock .menu .list-h {
  flex-wrap: nowrap;
  -webkit-flex-wrap: nowrap;
  -khtml-flex-wrap: nowrap;
  -moz-flex-wrap: nowrap;
  -o-flex-wrap: nowrap;
  -ms-flex-wrap: nowrap;
  margin: 4px;
}
.cover-wrapper.dock .menu .list-h a+a {
  margin-left: 4px;
}
@media screen and (max-width: 500px) {
  .cover-wrapper.dock .menu .list-h {
    overflow-x: scroll;
  }
  .cover-wrapper.dock .menu .list-h::-webkit-scrollbar {
    height: 0;
    width: 0;
  }
  .cover-wrapper.dock .menu .list-h::-webkit-scrollbar-track-piece {
    background: transparent;
  }
  .cover-wrapper.dock .menu .list-h::-webkit-scrollbar-thumb {
    background: #3dd9b6;
    cursor: pointer;
    border-radius: 0;
    -webkit-border-radius: 0;
  }
  .cover-wrapper.dock .menu .list-h::-webkit-scrollbar-thumb:hover {
    background: #ff5722;
  }
}
@supports (backdrop-filter: blur(20px)) {
  .cover-wrapper.dock .menu {
    background: rgba(255,255,255,0.5);
    backdrop-filter: saturate(200%) blur(20px);
  }
}
@font-face {
  font-family: 'UbuntuMono';
  src: url("https://unpkg.com/volantis-static@0.0.1654736714924/media/fonts/UbuntuMono/UbuntuMono-Regular.ttf");
  font-weight: 'normal';
  font-style: 'normal';
  font-display: swap;
}
@font-face {
  font-family: 'Varela Round';
  src: url("https://unpkg.com/volantis-static@0.0.1654736714924/media/fonts/VarelaRound/VarelaRound-Regular.ttf");
  font-weight: 'normal';
  font-style: 'normal';
  font-display: swap;
}
.l_header {
  position: fixed;
  z-index: 1000;
  top: 0;
  width: 100%;
  height: 64px;
  background: var(--color-card);
  box-shadow: 0 1px 2px 0px rgba(0,0,0,0.1);
  -webkit-box-shadow: 0 1px 2px 0px rgba(0,0,0,0.1);
}
.l_header.auto {
  transition: opacity 0.4s ease;
  -webkit-transition: opacity 0.4s ease;
  -khtml-transition: opacity 0.4s ease;
  -moz-transition: opacity 0.4s ease;
  -o-transition: opacity 0.4s ease;
  -ms-transition: opacity 0.4s ease;
  visibility: hidden;
}
.l_header.auto.show {
  opacity: 1 !important;
  -webkit-opacity: 1 !important;
  -moz-opacity: 1 !important;
  visibility: visible;
}
.l_header .container {
  margin-left: 16px;
  margin-right: 16px;
}
.l_header #wrapper {
  height: 100%;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}
.l_header #wrapper .nav-main,
.l_header #wrapper .nav-sub {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  flex-wrap: nowrap;
  -webkit-flex-wrap: nowrap;
  -khtml-flex-wrap: nowrap;
  -moz-flex-wrap: nowrap;
  -o-flex-wrap: nowrap;
  -ms-flex-wrap: nowrap;
  justify-content: space-between;
  -webkit-justify-content: space-between;
  -khtml-justify-content: space-between;
  -moz-justify-content: space-between;
  -o-justify-content: space-between;
  -ms-justify-content: space-between;
  align-items: center;
}
.l_header #wrapper .nav-main {
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
.l_header #wrapper.sub .nav-main {
  transform: translateY(-64px);
  -webkit-transform: translateY(-64px);
  -khtml-transform: translateY(-64px);
  -moz-transform: translateY(-64px);
  -o-transform: translateY(-64px);
  -ms-transform: translateY(-64px);
}
.l_header #wrapper .nav-sub {
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
  opacity: 0;
  -webkit-opacity: 0;
  -moz-opacity: 0;
  height: 64px;
  width: calc(100% - 2 * 16px);
  position: absolute;
}
.l_header #wrapper .nav-sub ::-webkit-scrollbar {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
}
@media screen and (min-width: 2048px) {
  .l_header #wrapper .nav-sub {
    max-width: 55vw;
    margin: auto;
  }
}
.l_header #wrapper.sub .nav-sub {
  opacity: 1;
  -webkit-opacity: 1;
  -moz-opacity: 1;
}
.l_header #wrapper .title {
  position: relative;
  color: var(--color-text);
  padding-left: 24px;
  max-height: 64px;
}
.l_header #wrapper .nav-main .title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
  line-height: 64px;
  padding: 0 24px;
  font-size: 1.25rem;
  font-family: "Varela Round", "PingFang SC", "Microsoft YaHei", Helvetica, Arial, Helvetica, monospace;
}
.l_header #wrapper .nav-main .title img {
  height: 64px;
}
.l_header .nav-sub {
  max-width: 1080px;
  margin: auto;
}
.l_header .nav-sub .title {
  font-weight: bold;
  font-family: UbuntuMono, "Varela Round", "PingFang SC", "Microsoft YaHei", Helvetica, Arial, Menlo, Monaco, monospace, sans-serif;
  line-height: 1.2;
  max-height: 64px;
  white-space: normal;
  flex-shrink: 1;
}
.l_header .switcher {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
  line-height: 64px;
  align-items: center;
}
.l_header .switcher .s-toc {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
}
@media screen and (max-width: 768px) {
  .l_header .switcher .s-toc {
    display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
    display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
    display: -ms-flexbox /* TWEENER - IE 10 */;
    display: -webkit-flex /* NEW - Chrome */;
    display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
    display: flex;
  }
}
.l_header .switcher >li {
  height: 48px;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
  margin: 2px;
}
@media screen and (max-width: 500px) {
  .l_header .switcher >li {
    margin: 0 1px;
    height: 48px;
  }
}
.l_header .switcher >li >a {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  justify-content: center;
  -webkit-justify-content: center;
  -khtml-justify-content: center;
  -moz-justify-content: center;
  -o-justify-content: center;
  -ms-justify-content: center;
  align-items: center;
  width: 48px;
  height: 48px;
  padding: 0.85em 1.1em;
  border-radius: 100px;
  -webkit-border-radius: 100px;
  border: none;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
  color: #3dd9b6;
}
.l_header .switcher >li >a:hover {
  border: none;
}
.l_header .switcher >li >a.active,
.l_header .switcher >li >a:active {
  border: none;
  background: var(--color-site-bg);
}
@media screen and (max-width: 500px) {
  .l_header .switcher >li >a {
    width: 36px;
    height: 48px;
  }
}
.l_header .nav-sub .switcher {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
}
.l_header .m_search {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  height: 64px;
  width: 240px;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
@media screen and (max-width: 1024px) {
  .l_header .m_search {
    width: 44px;
    min-width: 44px;
  }
  .l_header .m_search input::placeholder {
    opacity: 0;
    -webkit-opacity: 0;
    -moz-opacity: 0;
  }
  .l_header .m_search:hover {
    width: 240px;
  }
  .l_header .m_search:hover input::placeholder {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@media screen and (min-width: 500px) {
  .l_header .m_search:hover .input {
    width: 100%;
  }
  .l_header .m_search:hover .input::placeholder {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
@media screen and (max-width: 500px) {
  .l_header .m_search {
    min-width: 0;
  }
  .l_header .m_search input::placeholder {
    opacity: 1;
    -webkit-opacity: 1;
    -moz-opacity: 1;
  }
}
.l_header .m_search .form {
  position: relative;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  width: 100%;
  align-items: center;
}
.l_header .m_search .icon {
  position: absolute;
  width: 36px;
  left: 5px;
  color: var(--color-meta);
}
@media screen and (max-width: 500px) {
  .l_header .m_search .icon {
    display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
    display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
    display: none;
  }
}
.l_header .m_search .input {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  padding-top: 8px;
  padding-bottom: 8px;
  line-height: 1.3;
  width: 100%;
  color: var(--color-text);
  background: #fafafa;
  box-shadow: none;
  -webkit-box-shadow: none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  padding-left: 40px;
  font-size: 0.875rem;
  border-radius: 8px;
  -webkit-border-radius: 8px;
  border: none;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
@media screen and (min-width: 500px) {
  .l_header .m_search .input:focus {
    box-shadow: 0 4px 8px 0px rgba(0,0,0,0.1);
    -webkit-box-shadow: 0 4px 8px 0px rgba(0,0,0,0.1);
  }
}
@media screen and (max-width: 500px) {
  .l_header .m_search .input {
    background: var(--color-block);
    padding-left: 8px;
    border: none;
  }
  .l_header .m_search .input:hover,
  .l_header .m_search .input:focus {
    border: none;
  }
}
@media (max-width: 500px) {
  .l_header .m_search {
    left: 0;
    width: 0;
    overflow: hidden;
    position: absolute;
    background: #fff;
    transition: all 0.28s ease;
    -webkit-transition: all 0.28s ease;
    -khtml-transition: all 0.28s ease;
    -moz-transition: all 0.28s ease;
    -o-transition: all 0.28s ease;
    -ms-transition: all 0.28s ease;
  }
  .l_header .m_search .input {
    border-radius: 32px;
    -webkit-border-radius: 32px;
    margin-left: 16px;
    padding-left: 16px;
  }
  .l_header.z_search-open .m_search {
    width: 100%;
  }
  .l_header.z_search-open .m_search .input {
    width: calc(100% - 120px);
  }
}
ul.m-pc >li>a {
  color: inherit;
  border-bottom: 2px solid transparent;
}
ul.m-pc >li>a:active,
ul.m-pc >li>a.active {
  border-bottom: 2px solid #3dd9b6;
}
ul.m-pc li:hover >ul.list-v,
ul.list-v li:hover >ul.list-v {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
}
ul.nav-list-h {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: -ms-flexbox /* TWEENER - IE 10 */;
  display: -webkit-flex /* NEW - Chrome */;
  display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
  display: flex;
  align-items: stretch;
}
ul.nav-list-h>li {
  position: relative;
  justify-content: center;
  -webkit-justify-content: center;
  -khtml-justify-content: center;
  -moz-justify-content: center;
  -o-justify-content: center;
  -ms-justify-content: center;
  height: 100%;
  line-height: 2.4;
  border-radius: 4px;
  -webkit-border-radius: 4px;
}
ul.nav-list-h>li >a {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 600;
}
ul.list-v {
  z-index: 1;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
  position: absolute;
  background: var(--color-card);
  box-shadow: 0 2px 4px 0px rgba(0,0,0,0.08), 0 4px 8px 0px rgba(0,0,0,0.08), 0 8px 16px 0px rgba(0,0,0,0.08);
  -webkit-box-shadow: 0 2px 4px 0px rgba(0,0,0,0.08), 0 4px 8px 0px rgba(0,0,0,0.08), 0 8px 16px 0px rgba(0,0,0,0.08);
  margin-top: -6px;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  padding: 8px 0;
}
ul.list-v.show {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
}
ul.list-v hr {
  margin-top: 8px;
  margin-bottom: 8px;
}
ul.list-v >li {
  white-space: nowrap;
  word-break: keep-all;
}
ul.list-v >li.header {
  font-size: 0.78125rem;
  font-weight: bold;
  line-height: 2em;
  color: var(--color-meta);
  margin: 8px 16px 4px;
}
ul.list-v >li.header i {
  margin-right: 8px;
}
ul.list-v >li ul {
  margin-left: 0;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
  margin-top: -40px;
}
ul.list-v .aplayer-container {
  min-height: 64px;
  padding: 6px 16px;
}
ul.list-v >li>a {
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  color: var(--color-list);
  font-size: 0.875rem;
  font-weight: bold;
  line-height: 36px;
  padding: 0 20px 0 16px;
  text-overflow: ellipsis;
  margin: 0 4px;
  border-radius: 4px;
  -webkit-border-radius: 4px;
}
@media screen and (max-width: 1024px) {
  ul.list-v >li>a {
    line-height: 40px;
  }
}
ul.list-v >li>a >i {
  margin-right: 8px;
}
ul.list-v >li>a:active,
ul.list-v >li>a.active {
  color: var(--color-list-hl);
}
ul.list-v >li>a:hover {
  color: var(--color-list-hl);
  background: var(--color-site-bg);
}
.l_header .menu >ul>li>a {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: block;
  padding: 0 8px;
}
.l_header .menu >ul>li>a >i {
  margin-right: 4px;
}
.l_header ul.nav-list-h>li {
  color: var(--color-list);
  line-height: 64px;
}
.l_header ul.nav-list-h>li >a {
  max-height: 64px;
  overflow: hidden;
  color: inherit;
}
.l_header ul.nav-list-h>li >a:active,
.l_header ul.nav-list-h>li >a.active {
  color: #3dd9b6;
}
.l_header ul.nav-list-h>li:hover>a {
  color: var(--color-list-hl);
}
.l_header ul.nav-list-h>li i.music {
  animation: rotate-effect 1.5s linear infinite;
  -webkit-animation: rotate-effect 1.5s linear infinite;
  -khtml-animation: rotate-effect 1.5s linear infinite;
  -moz-animation: rotate-effect 1.5s linear infinite;
  -o-animation: rotate-effect 1.5s linear infinite;
  -ms-animation: rotate-effect 1.5s linear infinite;
}
@-moz-keyframes rotate-effect {
  0% {
    transform: rotate(0);
    -webkit-transform: rotate(0);
    -khtml-transform: rotate(0);
    -moz-transform: rotate(0);
    -o-transform: rotate(0);
    -ms-transform: rotate(0);
  }
  25% {
    transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -khtml-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
  }
  50% {
    transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
    -khtml-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
    -o-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
  }
  75% {
    transform: rotate(270deg);
    -webkit-transform: rotate(270deg);
    -khtml-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
    -o-transform: rotate(270deg);
    -ms-transform: rotate(270deg);
  }
  100% {
    transform: rotate(360deg);
    -webkit-transform: rotate(360deg);
    -khtml-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
  }
}
@-webkit-keyframes rotate-effect {
  0% {
    transform: rotate(0);
    -webkit-transform: rotate(0);
    -khtml-transform: rotate(0);
    -moz-transform: rotate(0);
    -o-transform: rotate(0);
    -ms-transform: rotate(0);
  }
  25% {
    transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -khtml-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
  }
  50% {
    transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
    -khtml-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
    -o-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
  }
  75% {
    transform: rotate(270deg);
    -webkit-transform: rotate(270deg);
    -khtml-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
    -o-transform: rotate(270deg);
    -ms-transform: rotate(270deg);
  }
  100% {
    transform: rotate(360deg);
    -webkit-transform: rotate(360deg);
    -khtml-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
  }
}
@-o-keyframes rotate-effect {
  0% {
    transform: rotate(0);
    -webkit-transform: rotate(0);
    -khtml-transform: rotate(0);
    -moz-transform: rotate(0);
    -o-transform: rotate(0);
    -ms-transform: rotate(0);
  }
  25% {
    transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -khtml-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
  }
  50% {
    transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
    -khtml-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
    -o-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
  }
  75% {
    transform: rotate(270deg);
    -webkit-transform: rotate(270deg);
    -khtml-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
    -o-transform: rotate(270deg);
    -ms-transform: rotate(270deg);
  }
  100% {
    transform: rotate(360deg);
    -webkit-transform: rotate(360deg);
    -khtml-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
  }
}
@keyframes rotate-effect {
  0% {
    transform: rotate(0);
    -webkit-transform: rotate(0);
    -khtml-transform: rotate(0);
    -moz-transform: rotate(0);
    -o-transform: rotate(0);
    -ms-transform: rotate(0);
  }
  25% {
    transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -khtml-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
  }
  50% {
    transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
    -khtml-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
    -o-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
  }
  75% {
    transform: rotate(270deg);
    -webkit-transform: rotate(270deg);
    -khtml-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
    -o-transform: rotate(270deg);
    -ms-transform: rotate(270deg);
  }
  100% {
    transform: rotate(360deg);
    -webkit-transform: rotate(360deg);
    -khtml-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
  }
}
.menu-phone li ul.list-v {
  right: calc(100% - 0.5 * 16px);
}
.menu-phone li ul.list-v ul {
  right: calc(100% - 0.5 * 16px);
}
#wrapper {
  max-width: 1080px;
  margin: auto;
}
@media screen and (min-width: 2048px) {
  #wrapper {
    max-width: 55vw;
  }
}
#wrapper .menu {
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  -webkit-flex: 1 1;
  -ms-flex: 1 1;
  flex: 1 1;
  margin: 0 16px 0 0;
}
#wrapper .menu .list-v ul {
  left: calc(100% - 0.5 * 16px);
}
.menu-phone {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
  margin-top: 16px;
  right: 8px;
  transition: all 0.28s ease;
  -webkit-transition: all 0.28s ease;
  -khtml-transition: all 0.28s ease;
  -moz-transition: all 0.28s ease;
  -o-transition: all 0.28s ease;
  -ms-transition: all 0.28s ease;
}
.menu-phone ul {
  right: calc(100% - 0.5 * 16px);
}
@media screen and (max-width: 500px) {
  .menu-phone {
    display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
    display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
    display: block;
  }
}
.l_header {
  max-width: 65vw;
  left: calc((100% - 65vw) * 0.5);
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
}
@media screen and (max-width: 2048px) {
  .l_header {
    max-width: 1112px;
    left: calc((100% - 1112px) * 0.5);
  }
}
@media screen and (max-width: 1112px) {
  .l_header {
    left: 0;
    border-radius: 0;
    -webkit-border-radius: 0;
    max-width: 100%;
  }
}
@media screen and (max-width: 500px) {
  .l_header .container {
    margin-left: 0;
    margin-right: 0;
  }
  .l_header #wrapper .nav-main .title {
    padding-left: 16px;
    padding-right: 16px;
  }
  .l_header #wrapper .nav-sub {
    width: 100%;
  }
  .l_header #wrapper .nav-sub .title {
    overflow-y: scroll;
    margin-top: 2px;
    padding: 8px 16px;
  }
  .l_header #wrapper .switcher {
    display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
    display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
    display: -ms-flexbox /* TWEENER - IE 10 */;
    display: -webkit-flex /* NEW - Chrome */;
    display: flex /* NEW, Spec - Opera 12.1, Firefox 20+ */;
    display: flex;
    margin-right: 8px;
  }
  .l_header .menu {
    display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
    display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
    display: none;
  }
}
@media screen and (max-width: 500px) {
  .list-v li {
    max-width: 270px;
  }
}
#u-search {
  display: -webkit-box /* OLD - iOS 6-, Safari 3.1-6 */;
  display: -moz-box /* OLD - Firefox 19- (buggy but mostly works) */;
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 60px 20px;
  z-index: 1001;
}
@media screen and (max-width: 680px) {
  #u-search {
    padding: 0px;
  }
}

  </style>
  <link rel="stylesheet" href="/css/style.css" media="print" onload="this.media='all';this.onload=null">
  <noscript><link rel="stylesheet" href="/css/style.css"></noscript>
  
<script>
if (/*@cc_on!@*/false || (!!window.MSInputMethodContext && !!document.documentMode))
    document.write(
	'<style>'+
		'html{'+
			'overflow-x: hidden !important;'+
			'overflow-y: hidden !important;'+
		'}'+
		'.kill-ie{'+
			'text-align:center;'+
			'height: 100%;'+
			'margin-top: 15%;'+
			'margin-bottom: 5500%;'+
		'}'+
    '.kill-t{'+
      'font-size: 2rem;'+
    '}'+
    '.kill-c{'+
      'font-size: 1.2rem;'+
    '}'+
		'#l_header,#l_body{'+
			'display: none;'+
		'}'+
	'</style>'+
    '<div class="kill-ie">'+
        `<span class="kill-t"><b>Sorry, your browser cannot access this site</b></span><br/>`+
        `<span class="kill-c">Microsoft has terminated support for Internet Explorer (IE) 10 and earlier versions in 2016. <br/>There are great security risks to continue using it. Please use contemporary mainstream browsers to access.</span><br/>`+
        `<a target="_blank" rel="noopener" href="https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge/"><strong>Learn more ></strong></a>`+
    '</div>');
</script>


<noscript>
	<style>
		html{
			overflow-x: hidden !important;
			overflow-y: hidden !important;
		}
		.kill-noscript{
			text-align:center;
			height: 100%;
			margin-top: 15%;
			margin-bottom: 5500%;
		}
    .kill-t{
      font-size: 2rem;
    }
    .kill-c{
      font-size: 1.2rem;
    }
		#l_header,#l_body{
			display: none;
		}
	</style>
    <div class="kill-noscript">
        <span class="kill-t"><b>Sorry, your browser cannot access this site</b></span><br/>
        <span class="kill-c">This page requires browser support (enable) JavaScript</span><br/>
        <a target="_blank" rel="noopener" href="https://www.baidu.com/s?wd=启用JavaScript"><strong>Learn more ></strong></a>
    </div>
</noscript>


  <script>
  /************这个文件存放不需要重载的全局变量和全局函数*********/
  window.volantis = {}; // volantis 全局变量
  volantis.debug = "env"; // 调试模式
  volantis.dom = {}; // 页面Dom see: /source/js/app.js etc.

  volantis.GLOBAL_CONFIG ={
    debug: "env",
    cdn: {"js":{"app":"/js/app.js","parallax":"/js/plugins/parallax.js","rightMenu":"/js/plugins/rightMenu.js","rightMenus":"/js/plugins/rightMenus.js","sites":"/js/plugins/tags/sites.js","friends":"/js/plugins/tags/friends.js","contributors":"/js/plugins/tags/contributors.js","search":"/js/search/hexo.js"},"css":{"style":"/css/style.css"}},
    default: {"avatar":"https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/avatar/round/3442075.svg","link":"https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/link/8f277b4ee0ecd.svg","cover":"https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/cover/76b86c0226ffd.svg","image":"https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/image/2659360.svg"},
    lastupdate: new Date(1739433735785),
    sidebar: {
      for_page: ["blogger","category","tagcloud","donate"],
      for_post: ["toc"],
      webinfo: {
        lastupd: {
          enable: true,
          friendlyShow: true
        },
        runtime: {
          data: "2020/01/01",
          unit: "天"
        }
      }
    },
    plugins: {
      message: {"enable":true,"css":"https://unpkg.com/volantis-static@0.0.1654736714924/libs/izitoast/dist/css/iziToast.min.css","js":"https://unpkg.com/volantis-static@0.0.1654736714924/libs/izitoast/dist/js/iziToast.min.js","icon":{"default":"fa-solid fa-info-circle light-blue","quection":"fa-solid fa-question-circle light-blue"},"time":{"default":5000,"quection":20000},"position":"topRight","transitionIn":"bounceInLeft","transitionOut":"fadeOutRight","titleColor":"var(--color-text)","messageColor":"var(--color-text)","backgroundColor":"var(--color-card)","zindex":2147483647,"copyright":{"enable":true,"title":"知识共享许可协议","message":"请遵守 CC BY-NC-SA 4.0 协议。","icon":"far fa-copyright light-blue"},"aplayer":{"enable":true,"play":"fa-solid fa-play","pause":"fa-solid fa-pause"},"rightmenu":{"enable":true,"notice":true}},
      fancybox: {"css":"https://unpkg.com/volantis-static@0.0.1654736714924/libs/@fancyapps/ui/dist/fancybox.css","js":"https://unpkg.com/volantis-static@0.0.1654736714924/libs/@fancyapps/ui/dist/fancybox.umd.js"},
      
      
      
    }
  }

  /******************** volantis.EventListener ********************************/
  // 事件监听器 see: /source/js/app.js
  volantis.EventListener = {}
  // 这里存放pjax切换页面时将被移除的事件监听器
  volantis.EventListener.list = []
  //构造方法
  function volantisEventListener(type, f, ele) {
    this.type = type
    this.f = f
    this.ele = ele
  }
  // 移除事件监听器
  volantis.EventListener.remove = () => {
    volantis.EventListener.list.forEach(function (i) {
      i.ele.removeEventListener(i.type, i.f, false)
    })
    volantis.EventListener.list = []
  }
  /******************** volantis.dom.$ ********************************/
  // 注：这里没有选择器，也没有forEach一次只处理一个dom，这里重新封装主题常用的dom方法，返回的是dom对象，对象包含了以下方法，同时保留dom的原生API
  function volantisDom(ele) {
    if (!ele) ele = document.createElement("div")
    this.ele = ele;
    // ==============================================================
    this.ele.find = (c) => {
      let q = this.ele.querySelector(c)
      if (q)
        return new volantisDom(q)
    }
    // ==============================================================
    this.ele.hasClass = (c) => {
      return this.ele.className.match(new RegExp('(\\s|^)' + c + '(\\s|$)'));
    }
    this.ele.addClass = (c) => {
      this.ele.classList.add(c);
      return this.ele
    }
    this.ele.removeClass = (c) => {
      this.ele.classList.remove(c);
      return this.ele
    }
    this.ele.toggleClass = (c) => {
      if (this.ele.hasClass(c)) {
        this.ele.removeClass(c)
      } else {
        this.ele.addClass(c)
      }
      return this.ele
    }
    // ==============================================================
    // 参数 r 为 true 表示pjax切换页面时事件监听器将被移除，false不移除
    this.ele.on = (c, f, r = 1) => {
      this.ele.addEventListener(c, f, false)
      if (r) {
        volantis.EventListener.list.push(new volantisEventListener(c, f, this.ele))
      }
      return this.ele
    }
    this.ele.click = (f, r) => {
      this.ele.on("click", f, r)
      return this.ele
    }
    this.ele.scroll = (f, r) => {
      this.ele.on("scroll", f, r)
      return this.ele
    }
    // ==============================================================
    this.ele.html = (c) => {
      // if(c=== undefined){
      //   return this.ele.innerHTML
      // }else{
      this.ele.innerHTML = c
      return this.ele
      // }
    }
    // ==============================================================
    this.ele.hide = (c) => {
      this.ele.style.display = "none"
      return this.ele
    }
    this.ele.show = (c) => {
      this.ele.style.display = "block"
      return this.ele
    }
    // ==============================================================
    return this.ele
  }
  volantis.dom.$ = (ele) => {
    return !!ele ? new volantisDom(ele) : null;
  }
  /******************** RunItem ********************************/
  function RunItem() {
    this.list = []; // 存放回调函数
    this.start = () => {
      for (var i = 0; i < this.list.length; i++) {
        this.list[i].run();
      }
    };
    this.push = (fn, name, setRequestAnimationFrame = true) => {
      let myfn = fn
      if (setRequestAnimationFrame) {
        myfn = ()=>{
          volantis.requestAnimationFrame(fn)
        }
      }
      var f = new Item(myfn, name);
      this.list.push(f);
    };
    this.remove = (name) =>{
      for (let index = 0; index < this.list.length; index++) {
        const e = this.list[index];
        if (e.name == name) {
          this.list.splice(index,1);
        }
      }
    }
    // 构造一个可以run的对象
    function Item(fn, name) {
      // 函数名称
      this.name = name || fn.name;
      // run方法
      this.run = () => {
        try {
          fn()
        } catch (error) {
          console.log(error);
        }
      };
    }
  }
  /******************** Pjax ********************************/
  // /layout/_plugins/pjax/index.ejs
  // volantis.pjax.send(callBack[,"callBackName"]) 传入pjax:send回调函数
  // volantis.pjax.push(callBack[,"callBackName"]) 传入pjax:complete回调函数
  // volantis.pjax.error(callBack[,"callBackName"]) 传入pjax:error回调函数
  volantis.pjax = {};
  volantis.pjax.method = {
    complete: new RunItem(),
    error: new RunItem(),
    send: new RunItem(),
  };
  volantis.pjax = Object.assign(volantis.pjax, {
    push: volantis.pjax.method.complete.push,
    error: volantis.pjax.method.error.push,
    send: volantis.pjax.method.send.push,
  });
  /******************** RightMenu ********************************/
  // volantis.rightmenu.handle(callBack[,"callBackName"]) 外部菜单项控制
  // 可在 volantis.mouseEvent 处获取右键事件
  volantis.rightmenu = {};
  volantis.rightmenu.method = {
    handle: new RunItem(),
  }
  volantis.rightmenu = Object.assign(volantis.rightmenu, {
    handle: volantis.rightmenu.method.handle.push,
  });
  /********************  Dark Mode  ********************************/
  // /layout/_partial/scripts/darkmode.ejs
  // volantis.dark.mode 当前模式 dark or light
  // volantis.dark.toggle() 暗黑模式触发器
  // volantis.dark.push(callBack[,"callBackName"]) 传入触发器回调函数
  volantis.dark = {};
  volantis.dark.method = {
    toggle: new RunItem(),
  };
  volantis.dark = Object.assign(volantis.dark, {
    push: volantis.dark.method.toggle.push,
  });
  /********************  Message  ********************************/
  // VolantisApp.message
  /********************  isMobile  ********************************/
  // /source/js/app.js
  // volantis.isMobile
  // volantis.isMobileOld
  /********************脚本动态加载函数********************************/
  // volantis.js(src, cb)  cb 可以传入onload回调函数 或者 JSON对象 例如: volantis.js("src", ()=>{}) 或 volantis.js("src", {defer:true,onload:()=>{}})
  // volantis.css(src)

  // 返回Promise对象，如下方法同步加载资源，这利于处理文件资源之间的依赖关系，例如：APlayer 需要在 MetingJS 之前加载
  // (async () => {
  //     await volantis.js("...theme.plugins.aplayer.js.aplayer...")
  //     await volantis.js("...theme.plugins.aplayer.js.meting...")
  // })();

  // 已经加入了setTimeout
  volantis.js = (src, cb) => {
    return new Promise(resolve => {
      setTimeout(function () {
        var HEAD = document.getElementsByTagName("head")[0] || document.documentElement;
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        if (cb) {
          if (JSON.stringify(cb)) {
            for (let p in cb) {
              if (p == "onload") {
                script[p] = () => {
                  cb[p]()
                  resolve()
                }
              } else {
                script[p] = cb[p]
                script.onload = resolve
              }
            }
          } else {
            script.onload = () => {
              cb()
              resolve()
            };
          }
        } else {
          script.onload = resolve
        }
        script.setAttribute("src", src);
        HEAD.appendChild(script);
      });
    });
  }
  volantis.css = (src) => {
    return new Promise(resolve => {
      setTimeout(function () {
        var link = document.createElement('link');
        link.rel = "stylesheet";
        link.href = src;
        link.onload = resolve;
        document.getElementsByTagName("head")[0].appendChild(link);
      });
    });
  }
  /********************按需加载的插件********************************/
  // volantis.import.jQuery().then(()=>{})
  volantis.import = {
    jQuery: () => {
      if (typeof jQuery == "undefined") {
        return volantis.js("https://unpkg.com/volantis-static@0.0.1654736714924/libs/jquery/dist/jquery.min.js")
      } else {
        return new Promise(resolve => {
          resolve()
        });
      }
    }
  }
  /********************** requestAnimationFrame ********************************/
  // 1、requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来，在一次重绘或回流中就完成，并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率，一般来说，这个频率为每秒60帧。
  // 2、在隐藏或不可见的元素中，requestAnimationFrame 将不会进行重绘或回流，这当然就意味着更少的的 cpu，gpu 和内存使用量。
  volantis.requestAnimationFrame = (fn)=>{
    if (!window.requestAnimationFrame) {
      window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
    }
    window.requestAnimationFrame(fn)
  }
  /************************ layoutHelper *****************************************/
  volantis.layoutHelper = (helper, html, opt)=>{
    opt = Object.assign({clean:false, pjax:true}, opt)
    function myhelper(helper, html, clean) {
      volantis.tempDiv = document.createElement("div");
      volantis.tempDiv.innerHTML = html;
      let layoutHelper = document.querySelector("#layoutHelper-"+helper)
      if (layoutHelper) {
        if (clean) {
          layoutHelper.innerHTML = ""
        }
        layoutHelper.append(volantis.tempDiv);
      }
    }
    myhelper(helper, html, opt.clean)
    if (opt.pjax) {
      volantis.pjax.push(()=>{
        myhelper(helper, html, opt.clean)
      },"layoutHelper-"+helper)
    }
  }
  /****************************** 滚动事件处理 ****************************************/
  volantis.scroll = {
    engine: new RunItem(),
    unengine: new RunItem(),
  };
  volantis.scroll = Object.assign(volantis.scroll, {
    push: volantis.scroll.engine.push,
  });
  // 滚动条距离顶部的距离
  volantis.scroll.getScrollTop = () =>{
    let scrollPos;
    if (window.pageYOffset) {
      scrollPos = window.pageYOffset;
    } else if (document.compatMode && document.compatMode != 'BackCompat') {
      scrollPos = document.documentElement.scrollTop;
    } else if (document.body) {
      scrollPos = document.body.scrollTop;
    }
    return scrollPos;
  }
  // 使用 requestAnimationFrame 处理滚动事件
  // `volantis.scroll.del` 中存储了一个数值, 该数值检测一定时间间隔内滚动条滚动的位移, 数值的检测频率是浏览器的刷新频率. 数值为正数时, 表示向下滚动. 数值为负数时, 表示向上滚动.
  volantis.scroll.handleScrollEvents = () => {
    volantis.scroll.lastScrollTop = volantis.scroll.getScrollTop()
    function loop() {
      const scrollTop = volantis.scroll.getScrollTop();
      if (volantis.scroll.lastScrollTop !== scrollTop) {
        volantis.scroll.del = scrollTop - volantis.scroll.lastScrollTop;
        volantis.scroll.lastScrollTop = scrollTop;
        // if (volantis.scroll.del > 0) {
        //   console.log("向下滚动");
        // } else {
        //   console.log("向上滚动");
        // }
        // 注销过期的unengine未滚动事件
        volantis.scroll.unengine.list=[]
        volantis.scroll.engine.start();
      }else{
        volantis.scroll.unengine.start();
      }
      volantis.requestAnimationFrame(loop)
    }
    volantis.requestAnimationFrame(loop)
  }
  volantis.scroll.handleScrollEvents()
  volantis.scroll.ele = null;
  // 触发页面滚动至目标元素位置
  volantis.scroll.to = (ele, option = {}) => {
    if (!ele) return;
    volantis.scroll.ele = ele;
    // 默认配置
    opt = {
      top: ele.getBoundingClientRect().top + document.documentElement.scrollTop,
      behavior: "smooth"
    }
    // 定义配置
    if ("top" in option) {
      opt.top = option.top
    }
    if ("behavior" in option) {
      opt.behavior = option.behavior
    }
    if ("addTop" in option) {
      opt.top += option.addTop
    }
    if (!("observerDic" in option)) {
      option.observerDic = 100
    }
    // 滚动
    window.scrollTo(opt);
    // 监视器
    // 监视并矫正元素滚动到指定位置
    // 用于处理 lazyload 引起的 cls 导致的定位失败问题
    // option.observer = false
    if (option.observer) {
      setTimeout(() => {
        if (volantis.scroll.ele != ele) {
          return
        }
        volantis.scroll.unengine.push(() => {
          let me = ele.getBoundingClientRect().top
          if(!(me >= -option.observerDic && me <= option.observerDic)){
            volantis.scroll.to(ele, option)
          }
          volantis.scroll.unengine.remove("unengineObserver")
        },"unengineObserver")
      },1000)
    }
  }
  /********************** Content Visibility ********************************/
  // 见 source/css/first.styl 如果遇到任何问题 删除 .post-story 即可
  // 一个元素被声明 content-visibility 属性后 如果元素不在 viewport 中 浏览器不会计算其后代元素样式和属性 从而节省 Style & Layout 耗时
  // content-visibility 的副作用: 锚点失效 等等(实验初期 暂不明确), 使用此方法清除样式
  volantis.cleanContentVisibility = ()=>{
    if (document.querySelector(".post-story")) {
      console.log("cleanContentVisibility");
      document.querySelectorAll(".post-story").forEach(e=>{
        e.classList.remove("post-story")
      })
    }
  }
  /******************************************************************************/
  /******************************************************************************/
  /******************************************************************************/
  //图像加载出错时的处理
  function errorImgAvatar(img) {
    img.src = "https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/avatar/round/3442075.svg";
    img.onerror = null;
  }
  function errorImgCover(img) {
    img.src = "https://unpkg.com/volantis-static@0.0.1654736714924/media/placeholder/cover/76b86c0226ffd.svg";
    img.onerror = null;
  }
  /******************************************************************************/
</script>

  <!-- import head_end begin -->
  <!-- import head_end end -->
  <!-- Custom Files headEnd begin-->
  
  <!-- Custom Files headEnd end-->
  <!-- front-matter head_end begin -->
  <!-- front-matter head_end end -->
</head>
  <body itemscope itemtype="http://schema.org/WebPage">
    <!-- import body_begin begin-->
    <!-- import body_begin end-->
    <!-- Custom Files bodyBegin begin-->
    
    <!-- Custom Files bodyBegin end-->
    <!-- front-matter body_begin begin -->
    <!-- front-matter body_begin end -->
    <header itemscope itemtype="http://schema.org/WPHeader" id="l_header" class="l_header auto shadow floatable blur show" style='opacity: 0' >
  <div class='container'>
  <div id='wrapper'>
    <div class='nav-sub'>
      <p class="title"></p>
      <ul class='switcher nav-list-h m-phone' id="pjax-header-nav-list">
        <li><a id="s-comment" class="fa-solid fa-comments fa-fw" target="_self"  href="/" onclick="return false;" title="comment"></a></li>
        
          <li><a id="s-toc" class="s-toc fa-solid fa-list fa-fw" target="_self"  href="/" onclick="return false;" title="toc"></a></li>
        
      </ul>
    </div>
		<div class="nav-main">
      
        
        <a class="title flat-box" target="_self" href='/'>
          
            <img no-lazy class='logo' src='https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/Logo-NavBar@3x.png'/>
          
          
          
        </a>
      

			<div class='menu navigation'>
				<ul class='nav-list-h m-pc'>
          
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/" title="博客"
                  
                  
                  
                    active-action="action-home"
                  >
                  <i class='fa-solid fa-rss fa-fw'></i>博客
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/categories/" title="分类"
                  
                  
                  
                    active-action="action-categories"
                  >
                  <i class='fa-solid fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/tags/" title="标签"
                  
                  
                  
                    active-action="action-tags"
                  >
                  <i class='fa-solid fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/archives/" title="归档"
                  
                  
                  
                    active-action="action-archives"
                  >
                  <i class='fa-solid fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/friends/" title="友链"
                  
                  
                  
                    active-action="action-friends"
                  >
                  <i class='fa-solid fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/about/" title="关于"
                  
                  
                  
                    active-action="action-about"
                  >
                  <i class='fa-solid fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
          
				</ul>
			</div>
      
      <div class="m_search">
        <form name="searchform" class="form u-search-form">
          <i class="icon fa-solid fa-search fa-fw"></i>
          <input type="text" class="input u-search-input" placeholder="Search..." />
        </form>
      </div>
      

			<ul class='switcher nav-list-h m-phone'>
				
					<li><a class="s-search fa-solid fa-search fa-fw" target="_self" href="/" onclick="return false;" title="search"></a></li>
				
				<li>
          <a class="s-menu fa-solid fa-bars fa-fw" target="_self" href="/" onclick="return false;" title="menu"></a>
          <ul class="menu-phone list-v navigation white-box">
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/" title="博客"
                  
                  
                  
                    active-action="action-home"
                  >
                  <i class='fa-solid fa-rss fa-fw'></i>博客
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/categories/" title="分类"
                  
                  
                  
                    active-action="action-categories"
                  >
                  <i class='fa-solid fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/tags/" title="标签"
                  
                  
                  
                    active-action="action-tags"
                  >
                  <i class='fa-solid fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/archives/" title="归档"
                  
                  
                  
                    active-action="action-archives"
                  >
                  <i class='fa-solid fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/friends/" title="友链"
                  
                  
                  
                    active-action="action-friends"
                  >
                  <i class='fa-solid fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box faa-parent animated-hover"
                href="/about/" title="关于"
                  
                  
                  
                    active-action="action-about"
                  >
                  <i class='fa-solid fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
            
          </ul>
        </li>
			</ul>

      <!-- Custom Files header begin -->
      
      <!-- Custom Files header end -->
		</div>
	</div>
  </div>
</header>

    <div id="l_body">
      <div id="l_cover">
  
    
      <!-- see: /layout/_partial/scripts/_ctrl/coverCtrl.ejs -->
      <div id="none" class='cover-wrapper post dock' style="display: none;">
        
  <div class='cover-bg lazyload placeholder' data-bg="https://gcore.jsdelivr.net/gh/MHG-LAB/cron@gh-pages/bing/bing.jpg"></div>

<div class='cover-body'>
  <div class='top'>
    
    
      <p class="title">Volantis</p>
    
    
  </div>
  <div class='bottom'>
    <div class='menu navigation'>
      <div class='list-h'>
        
          
            <a href="/v4/getting-started/"
              
              
              active-action="action-v4getting-started">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f5c3.svg'><p>文档</p>
            </a>
          
            <a href="/faqs/"
              
              
              active-action="action-faqs">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f516.svg'><p>帮助</p>
            </a>
          
            <a href="/examples/"
              
              
              active-action="action-examples">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f396.svg'><p>示例</p>
            </a>
          
            <a href="/contributors/"
              
              
              active-action="action-contributors">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f389.svg'><p>社区</p>
            </a>
          
            <a href="/archives/"
              
              
              active-action="action-archives">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f4f0.svg'><p>博客</p>
            </a>
          
            <a target="_blank" rel="noopener" href="https://github.com/volantis-x/hexo-theme-volantis/"
              
              
              active-action="action-https:githubcomvolantis-xhexo-theme-volantis">
              <img src='https://unpkg.com/volantis-static@0.0.1654736714924/media/twemoji/assets/svg/1f9ec.svg'><p>源码</p>
            </a>
          
        
      </div>
    </div>
  </div>
</div>

        <div id="scroll-down" style="display: none;"><i class="fa fa-chevron-down scroll-down-effects"></i></div>
      </div>
    
  
</div>

      <div id="safearea">
        <div class="body-wrapper">
          
<div id="l_main" class=''>
  <article itemscope itemtype="http://schema.org/Article" class="article post white-box reveal md shadow floatable blur article-type-post" id="post" itemscope itemprop="blogPost">
  <link itemprop="mainEntityOfPage" href="http://example.com/2023/12/22/JavaScript/">
  <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="Knowledge">
  </span>
  <span hidden itemprop="post" itemscope itemtype="http://schema.org/Post">
    <meta itemprop="name" content="Knowledge">
    <meta itemprop="description" content="html css node vue node">
  </span>
  


  
    <span hidden>
      <meta itemprop="image" content="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png">
    </span>
  
  <div class="article-meta" id="top">
    
    
    
      <h1 class="title" itemprop="name headline">
        JavaScript
      </h1>
      <div class='new-meta-box'>
        
          
            
<div class='new-meta-item author' itemprop="author" itemscope itemtype="http://schema.org/Person">
  <a itemprop="url" class='author' href="/" rel="nofollow">
    <img itemprop="image" src="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/apple-touch-icon.png" class="lazyload" data-srcset="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/apple-touch-icon.png" srcset="">
    <p itemprop="name">请设置文章作者</p>
  </a>
</div>

          
        
          
            

          
        
          
            <div class="new-meta-item date" itemprop="dateCreated datePublished" datetime="2023-12-22T11:11:03+08:00">
  <a class='notlink'>
    <i class="fa-solid fa-calendar-alt fa-fw" aria-hidden="true"></i>
    <p>发布于：Dec 22, 2023</p>
  </a>
</div>

          
        
          
            



          
        
        <!-- Custom Files topMeta begin-->
        
        <!-- Custom Files topMeta end-->
      </div>
    
  </div>


  <div id="layoutHelper-page-plugins"></div>
  <div id="post-body" itemprop="articleBody">
    <h2 id="localStorage"><a href="#localStorage" class="headerlink" title="localStorage"></a>localStorage</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 数据存在 localStorage里面可以长期保留，也就是说关闭页面后，存储在 localStorage 的数据还在，不会丢失。</span></span><br><span class="line"><span class="comment">// 不同的浏览器里localStorage 的存储大小不一样，比如有些大小是4M</span></span><br><span class="line"><span class="comment">// 方法：</span></span><br><span class="line"><span class="comment">// 1：访问本地storage对象，通过setItem（）输入键名和值建立了一个数据项</span></span><br><span class="line"><span class="comment">// localStorage.setItem(&#x27;first&#x27;, &#x27;abc&#x27;);</span></span><br><span class="line"><span class="comment">// 2：通过键名，得到一个localStorage的数据项</span></span><br><span class="line"><span class="comment">// var sec = localStorage.getItem(&#x27;second&#x27;);</span></span><br><span class="line"><span class="comment">// 3: 通过键名，删除一个localStorage的数据项</span></span><br><span class="line"><span class="comment">// localStorage.removeItem(&#x27;third&#x27;);</span></span><br><span class="line"><span class="comment">// 4：删除localStorage里面储存的所有数据项</span></span><br><span class="line"><span class="comment">// localStorage.clear();</span></span><br><span class="line"><span class="comment">// 5：返回存储对象第i个数据项的键名</span></span><br><span class="line"><span class="comment">// localStorage.key(i);</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="节流和防抖"><a href="#节流和防抖" class="headerlink" title="节流和防抖"></a>节流和防抖</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> div = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;div&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> button = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;button&#x27;</span>);</span><br><span class="line"><span class="keyword">let</span> count = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">doSomeThing</span>(<span class="params">e</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, e);</span><br><span class="line">  div.<span class="property">innerHTML</span> = count++;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;想要的结果&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> doSome = <span class="title function_">debounce</span>(doSomeThing, <span class="number">1000</span>);</span><br><span class="line">div.<span class="property">onmousemove</span> = doSome;</span><br><span class="line">button.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  doSome.<span class="title function_">cancel</span>();</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;清除成功&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 函数防抖的概念</span></span><br><span class="line"><span class="comment">// 在设定的执行周期内，只让最后一次生效，前面的的不生效，都认为是用户不小心抖动，</span></span><br><span class="line"><span class="comment">// 适合多次事件一次响应的情况。</span></span><br><span class="line"><span class="comment">// 应用场景</span></span><br><span class="line"><span class="comment">// 1、scroll事件滚动触发</span></span><br><span class="line"><span class="comment">// 2、搜索框输入查询</span></span><br><span class="line"><span class="comment">// 3、表单验证</span></span><br><span class="line"><span class="comment">// 4、按钮提交事件</span></span><br><span class="line"><span class="comment">// 5、浏览器窗口缩放，resize事件</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">debounce</span>(<span class="params">func, wait, immediate</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> timeout, result;</span><br><span class="line">  <span class="keyword">let</span> decounced = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> context = <span class="variable language_">this</span>;</span><br><span class="line">    <span class="keyword">const</span> args = <span class="variable language_">arguments</span>;</span><br><span class="line">    <span class="keyword">if</span> (timeout) <span class="built_in">clearInterval</span>(timeout);</span><br><span class="line">    <span class="keyword">if</span> (immediate) &#123;</span><br><span class="line">      <span class="keyword">let</span> callNow = !timeout;</span><br><span class="line">      timeout = <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        timeout = <span class="literal">null</span>;</span><br><span class="line">      &#125;, wait);</span><br><span class="line">      <span class="comment">// 立即执行</span></span><br><span class="line">      <span class="keyword">if</span> (callNow) result = func.<span class="title function_">apply</span>(context, args);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 不会立即执行</span></span><br><span class="line">      timeout = <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        func.<span class="title function_">apply</span>(context, args);</span><br><span class="line">      &#125;, wait);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">  &#125;;</span><br><span class="line">  decounced.<span class="property">cancel</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="built_in">clearTimeout</span>(timeout);</span><br><span class="line">    timeout = <span class="literal">null</span>;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> decounced;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> count1 = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">const</span> div = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;div&#x27;</span>);</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">doSomeThing</span>(<span class="params">e</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(e);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  div.<span class="property">innerHTML</span> = count++;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// div.onmousemove = throttle(doSomeThing, 2000, &#123; leading: false, trailing: true &#125;)</span></span><br><span class="line">div.<span class="property">onmousemove</span> = <span class="title function_">throttle</span>(doSomeThing, <span class="number">2000</span>, &#123;</span><br><span class="line">  <span class="attr">leading</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">trailing</span>: <span class="literal">false</span></span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 节流</span></span><br><span class="line"><span class="comment">// 原理：如果你持续触发事件，每隔一段时间，只执行一次事件</span></span><br><span class="line"><span class="comment">// 应用场景</span></span><br><span class="line"><span class="comment">// 1、DOM元素的拖拽功能实现</span></span><br><span class="line"><span class="comment">// 2、射击游戏</span></span><br><span class="line"><span class="comment">// 3、计算鼠标移动距离</span></span><br><span class="line"><span class="comment">// 4、监听scroll滚动事件</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// leading：第一次是否会输出true、false</span></span><br><span class="line"><span class="comment">// trailing：最后一次是否会被调用true、false</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">throttle</span>(<span class="params">func, wait, options</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> context, args, timeout;</span><br><span class="line">  <span class="keyword">let</span> old = <span class="number">0</span>; <span class="comment">// 时间戳</span></span><br><span class="line">  <span class="keyword">if</span> (!options) options = &#123;&#125;;</span><br><span class="line">  <span class="keyword">let</span> later = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    old = <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">valueOf</span>();</span><br><span class="line">    timeout = <span class="literal">null</span>;</span><br><span class="line">    func.<span class="title function_">apply</span>(context, args);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    context = <span class="variable language_">this</span>;</span><br><span class="line">    args = <span class="variable language_">arguments</span>;</span><br><span class="line">    <span class="keyword">let</span> now = <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">valueOf</span>();</span><br><span class="line">    <span class="keyword">if</span> (options.<span class="property">leading</span> === <span class="literal">false</span> &amp;&amp; !old) old = now;</span><br><span class="line">    <span class="keyword">if</span> (now - old &gt; wait) &#123;</span><br><span class="line">      <span class="comment">// 第一次会直接执行</span></span><br><span class="line">      <span class="keyword">if</span> (timeout) &#123;</span><br><span class="line">        <span class="built_in">clearTimeout</span>(timeout);</span><br><span class="line">        timeout = <span class="literal">null</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      func.<span class="title function_">apply</span>(context, args);</span><br><span class="line">      old = now;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (!timeout &amp;&amp; options.<span class="property">trailing</span> !== <span class="literal">false</span>) &#123;</span><br><span class="line">      <span class="comment">// 最后一次也会被执行</span></span><br><span class="line">      timeout = <span class="built_in">setTimeout</span>(later, wait);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h2 id="单行代码"><a href="#单行代码" class="headerlink" title="单行代码"></a>单行代码</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 数组去重</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">uniqueArr</span> = arr =&gt; [...<span class="keyword">new</span> <span class="title class_">Set</span>(arr)];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">uniqueArr</span>([<span class="string">&#x27;js&#x27;</span>, <span class="string">&#x27;js&#x27;</span>, <span class="string">&#x27;html&#x27;</span>, <span class="string">&#x27;js&#x27;</span>, <span class="string">&#x27;css&#x27;</span>, <span class="string">&#x27;html&#x27;</span>]));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 从url获取参数并转为对象</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">getParameters</span> = <span class="variable constant_">URL</span> =&gt;</span><br><span class="line">  <span class="title class_">JSON</span>.<span class="title function_">parse</span>(</span><br><span class="line">    <span class="string">`&#123;&quot;<span class="subst">$&#123;<span class="built_in">decodeURI</span>(URL.split(<span class="string">&#x27;?&#x27;</span>)[<span class="number">1</span>])</span></span></span><br><span class="line"><span class="subst"><span class="string">      .replace(/<span class="string">&quot;/g, &#x27;\\&quot;</span><span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">      .replace(/&amp;/g, &#x27;</span><span class="string">&quot;,&quot;</span><span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">      .replace(/=/g, &#x27;</span><span class="string">&quot;:&quot;</span><span class="string">&#x27;)&#125;&quot;&#125;`</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  );</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  getParameters(&#x27;</span>https://www.google.com.hk/search?q=js+md&amp;newwindow=<span class="number">1</span><span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查对象是否为空</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isEmpty = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Reflect.ownKeys(obj).length === 0 &amp;&amp; obj.constructor === Object;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isEmpty(&#123;&#125;), isEmpty(&#123; a: &#x27;</span><span class="string">&#x27; &#125;)); // true false</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 反转字符串</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const reverse = str =&gt; str.split(&#x27;</span><span class="string">&#x27;).reverse().join(&#x27;</span><span class="string">&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(reverse(&#x27;</span><span class="variable language_">this</span> is reverse<span class="string">&#x27;)); // esrever si siht</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 生成随机十六进制</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const randomHexColor = () =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  `#$&#123;Math.floor(Math.random() * 0xffffff)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .toString(16)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .padEnd(6, &#x27;</span><span class="number">0</span><span class="string">&#x27;)&#125;`;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(randomHexColor()); // #a2ce5b</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查当前选项卡是否在后台</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isTabActive = () =&gt; !document.hidden;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isTabActive());</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检测元素是否处于焦点</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const elementIsInFocus = el =&gt; el === document.activeElement;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// console.log(elementIsInFocus(anyElement));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查设备类型</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const judgeDeviceType = () =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i.test(</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    navigator.userAgent</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  )</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    ? &#x27;</span>Mobile<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    : &#x27;</span>PC<span class="string">&#x27;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(navigator.userAgent, judgeDeviceType()); // PC | Mobile</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 获取选定的文本</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const getSelectedText = () =&gt; window.getSelection().toString();</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(getSelectedText()); // 返回选中的内容</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 查询某天是否为工作日</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isWeekday = date =&gt; date.getDay() % 6 !== 0;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isWeekday(new Date(2022, 03, 11))); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 传时间戳返回时间描述文字</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const timeStampTransferDate = timeStamp =&gt; &#123;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  let date = new Date(timeStamp);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  return `$&#123;date.getFullYear()&#125;年$&#123;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    date.getMonth() + 1</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#125;月$&#123;date.getDate()&#125;日$&#123;date.getHours()&#125;时$&#123;date.getMinutes()&#125;分$&#123;date.getSeconds()&#125;秒`;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">&#125;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(timeStampTransferDate(new Date()));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将华氏温度转换为摄氏温度</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const fahrenheitToCelsius = fahrenheit =&gt; ((fahrenheit - 32) * 5) / 9;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(fahrenheitToCelsius(50));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将摄氏温度转华氏温度</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const celsiusToFahrenheit = celsius =&gt; (celsius * 9) / 5 + 32;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(celsiusToFahrenheit(100));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 两日期之间相差的天数</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const dayDiff = (date1, date2) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 86400000);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(dayDiff(new Date(&#x27;</span><span class="number">2021</span>-<span class="number">10</span>-<span class="number">21</span><span class="string">&#x27;), new Date(&#x27;</span><span class="number">2022</span>-<span class="number">02</span>-<span class="number">12</span><span class="string">&#x27;)));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将 RGB 转换为十六进制</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const rgbToHex = (r, g, b) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#x27;</span>#<span class="string">&#x27; + ((1 &lt;&lt; 24) + (r &lt;&lt; 16) + (g &lt;&lt; 8) + b).toString(16).slice(1);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(rgbToHex(255, 255, 255));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 计算数组平均值</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const average = arr =&gt; arr.reduce((a, b) =&gt; a + b) / arr.length;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(average([1, 9, 18, 36])); // 16</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查数字是偶数还是奇数</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isEven = num =&gt; num % 2 === 0;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isEven(2));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 清除所有 Cookie</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const clearCookies = document.cookie</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .split(&#x27;</span>;<span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .forEach(</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    cookie =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">      (document.cookie = cookie</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">        .replace(/^ +/, &#x27;</span><span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">        .replace(/=.*/, `=;expires=$&#123;new Date(0).toUTCString()&#125;;path=/`))</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  );</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const clearCookies2 = document.cookie</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .split(&#x27;</span>;<span class="string">&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .map(item =&gt; item.split(&#x27;</span>=<span class="string">&#x27;))</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .reduce((acc, [k, v]) =&gt; (acc[k.trim().replace(&#x27;</span><span class="string">&quot;&#x27;, &#x27;&#x27;)] = v) &amp;&amp; acc, &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将首字符串大写</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const capitalize = str =&gt; str.charAt(0).toUpperCase() + str.slice(1);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(capitalize(&#x27;follow for more&#x27;)); // Follow for more</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 找出一年中的哪一天，也是就当前月日是这年的第几天</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const dayOfYear = date =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(dayOfYear(new Date(&#x27;2023-01-02&#x27;)), dayOfYear(new Date()));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查日期是否有效</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isDateValid = (...val) =&gt; !Number.isNaN(new Date(...val).valueOf());</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isDateValid(&#x27;December 17, 1995 03:24:00&#x27;)); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 复制到剪贴板</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const copyToClipboard = text =&gt; navigator.clipboard.writeText(text);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(copyToClipboard(&#x27;Hello World&#x27;));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 从日期记录时间</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const timeFromDate = date =&gt; date.toTimeString().slice(0, 8);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(timeFromDate(new Date(2021, 0, 10, 17, 30, 0))); // 17:30:00</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检测暗模式</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isDarkMode =</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  window.matchMedia &amp;&amp;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  window.matchMedia(&#x27;(prefers-color-scheme: dark)&#x27;).matches;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isDarkMode); // false</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 打乱数组</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const shuffleArray = arr =&gt; arr.sort(() =&gt; 0.5 - Math.random());</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(shuffleArray([1, 2, 3, 4]));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将数字转化为千分位格式</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const toDecimalMark = num =&gt; num.toLocaleString(&#x27;en-US&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(toDecimalMark(12305030388.9087)); // &quot;</span><span class="number">12</span>,<span class="number">305</span>,<span class="number">030</span>,<span class="number">388.909</span><span class="string">&quot;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 多维数组转一维数组</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const deepFlatten = arr =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  [].concat(...arr.map(v =&gt; (Array.isArray(v) ? deepFlatten(v) : v)));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(deepFlatten([1, [2], [[3], 4], 5])); // [1,2,3,4,5]</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 过滤对象数组 真的很好用</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const data = [</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: 1, name: &#x27;john&#x27;, age: 24 &#125;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: 2, name: &#x27;mike&#x27;, age: 50 &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">];</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const reducedFilter = (data, keys, fn) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  data.filter(fn).map(el =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    keys.reduce((acc, key) =&gt; &#123;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">      acc[key] = el[key];</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">      return acc;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    &#125;, &#123;&#125;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  );</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(reducedFilter(data, [&#x27;id&#x27;, &#x27;name&#x27;], item =&gt; item.age &gt; 24)); // [&#123; id: 2, name: &#x27;mike&#x27;&#125;]</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 驼峰字字符串格式化</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const fromCamelCase = (str, separator = &#x27;_&#x27;) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  str</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .replace(/([a-z\d])([A-Z])/g, &#x27;$1&#x27; + separator + &#x27;$2&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, &#x27;$1&#x27; + separator + &#x27;$2&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .toLowerCase();</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(fromCamelCase(&#x27;someDatabaseFieldName&#x27;, &#x27; &#x27;)); // &#x27;some database field name&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(fromCamelCase(&#x27;someLabelThatNeedsToBeCamelized&#x27;, &#x27;-&#x27;)); // &#x27;some-label-that-needs-to-be-camelized&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(fromCamelCase(&#x27;someJavascriptProperty&#x27;, &#x27;_&#x27;)); // &#x27;some_javascript_property&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 是否为绝对地址</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isAbsoluteURL = str =&gt; /^[a-z][a-z0-9+.-]*:/.test(str);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isAbsoluteURL(&#x27;https://google.com&#x27;)); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isAbsoluteURL(&#x27;ftp://www.myserver.net&#x27;)); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isAbsoluteURL(&#x27;/foo/bar&#x27;)); // false</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 数组对象去重</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const arr = [</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: 1, name: &#x27;Jhon&#x27; &#125;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: 2, name: &#x27;sss&#x27; &#125;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: 1, name: &#x27;Jhon&#x27; &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">];</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const uniqueElementsBy = (arr, fn) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  arr.reduce((acc, v) =&gt; &#123;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    if (!acc.some(x =&gt; fn(v, x))) acc.push(v);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    return acc;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#125;, []);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(uniqueElementsBy(arr, (a, b) =&gt; a.id == b.id)); // [&#123;id: 1, name: &#x27;Jhon&#x27;&#125;, &#123;id: 2, name: &#x27;sss&#x27;&#125;]</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 常用密码组合正则</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// -长度8~20位字符，支持大小写字母、数字、符号三种字符中任意两种字符的组合</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const passwordReg = /(?!^(\d+|[a-zA-Z]+|[~!@#$%^&amp;*?]+)$)^[\w~!@#$%^&amp;*?]&#123;8,20&#125;$/;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 判断dom元素是否具有某个className</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const hasClass = (el, className) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  new RegExp(`(^|\\s)$&#123;className&#125;(\\s|$)`).test(el.className);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 获取数组交集</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const similarity = (arr, values) =&gt; arr.filter(v =&gt; values.includes(v));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(similarity([1, 2, 3], [1, 2, 4])); // [1,2]</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// JS 对象转 url 查询字符串</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const objectToQueryString = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.keys(obj)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .map(key =&gt; `$&#123;encodeURIComponent(key)&#125;=$&#123;encodeURIComponent(obj[key])&#125;`)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .join(&#x27;&amp;&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(objectToQueryString(&#123; name: &#x27;Jhon&#x27;, age: 18, address: &#x27;beijing&#x27; &#125;)); // name=Jhon&amp;age=18&amp;address=beijing</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 身份证正则</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const IDReg =</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  /(^[1-9]\d&#123;5&#125;(18|19|([23]\d))\d&#123;2&#125;((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d&#123;3&#125;[0-9Xx]$)|(^[1-9]\d&#123;5&#125;\d&#123;2&#125;((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d&#123;2&#125;[0-9Xx]$)/;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 随机生成六位数字验证码</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const code = Math.floor(Math.random() * 1000000)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .toString()</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .padStart(6, &#x27;0&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(code);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 快速创建数字数组</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const numArray = Array.from(new Array(10), (x, i) =&gt; i);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(numArray); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 删除Boolean 为 false 值</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log([0, false, true, undefined, null, &#x27;&#x27;, 12, 15].filter(Boolean));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将 cookie 转换为对象</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const cookies = document.cookie</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .split(&#x27;;&#x27;)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .map(item =&gt; item.split(&#x27;=&#x27;))</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  .reduce((acc, [k, v]) =&gt; (acc[k.trim().replace(&#x27;&quot;</span><span class="string">&#x27;, &#x27;</span><span class="string">&#x27;)] = v) &amp;&amp; acc, &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 获取一个元素的所有兄弟元素</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const siblings = ele =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  document.slice.call(ele.parentNode.children).filter(child =&gt; child !== ele);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 比较两个数组</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isEqual = (a, b) =&gt; JSON.stringify(a) === JSON.stringify(b);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isEqual2 = (a, b) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  a.length === b.length &amp;&amp; a.every((v, i) =&gt; v === b[i]);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isEqual([1, 2, 3], [1, 2, 3])); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(isEqual2([1, 2, 3], [1, &#x27;</span><span class="number">2</span><span class="string">&#x27;, 3])); // false</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 将对象数组转换为单个对象</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const array = [</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: &#x27;</span><span class="number">1</span><span class="string">&#x27;, name: &#x27;</span>Alpha<span class="string">&#x27;, gender: &#x27;</span>Male<span class="string">&#x27; &#125;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: &#x27;</span><span class="number">2</span><span class="string">&#x27;, name: &#x27;</span>Bravo<span class="string">&#x27;, gender: &#x27;</span>Male<span class="string">&#x27; &#125;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  &#123; id: &#x27;</span><span class="number">3</span><span class="string">&#x27;, name: &#x27;</span>Charlie<span class="string">&#x27;, gender: &#x27;</span>Female<span class="string">&#x27; &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">];</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const toObject = (arr, key) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  arr.reduce((a, b) =&gt; (&#123; ...a, [b[key]]: b &#125;), &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const toObject2 = (arr, key) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.fromEntries(arr.map(it =&gt; [it[key], it]));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(toObject(array, &#x27;</span>id<span class="string">&#x27;));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(toObject2(array, &#x27;</span>id<span class="string">&#x27;));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 根据对象数组的属性进行计数</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const countBy = (arr, prop) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  arr.reduce(</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    (prev, curr) =&gt; ((prev[curr[prop]] = ++prev[curr[prop]] || 1), prev),</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    &#123;&#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  );</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(countBy(array, &#x27;</span>gender<span class="string">&#x27;));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查多个对象是否相等</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const objectIsEqual = (...objects) =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  objects.every(obj =&gt; JSON.stringify(obj) === JSON.stringify(objects[0]));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(objectIsEqual(&#123; foo: &#x27;</span>bar<span class="string">&#x27; &#125;, &#123; foo: &#x27;</span>bar<span class="string">&#x27; &#125;)); // true</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(objectIsEqual(&#123; foo: &#x27;</span>bar<span class="string">&#x27; &#125;, &#123; bar: &#x27;</span>foo<span class="string">&#x27; &#125;)); // false</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 从对象数组中提取指定属性的值</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const pluck = (objs, property) =&gt; objs.map(obj =&gt; obj[property]);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(pluck(array, &#x27;</span>name<span class="string">&#x27;));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 反转对象的键和值</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const invert = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.keys(obj).reduce((res, k) =&gt; Object.assign(res, &#123; [obj[k]]: k &#125;), &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const invert1 = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.fromEntries(Object.entries(obj).map(([k, v]) =&gt; [v, k]));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(invert(&#123; a: &#x27;</span><span class="number">1</span><span class="string">&#x27;, b: &#x27;</span><span class="number">2</span><span class="string">&#x27;, c: &#x27;</span><span class="number">3</span><span class="string">&#x27; &#125;)); // &#123; 1: &#x27;</span>a<span class="string">&#x27;, 2: &#x27;</span>b<span class="string">&#x27;, 3: &#x27;</span>c<span class="string">&#x27; &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(invert1(&#123; a: &#x27;</span><span class="number">1</span><span class="string">&#x27;, b: &#x27;</span><span class="number">2</span><span class="string">&#x27;, c: &#x27;</span><span class="number">3</span><span class="string">&#x27; &#125;)); // &#123; 1: &#x27;</span>a<span class="string">&#x27;, 2: &#x27;</span>b<span class="string">&#x27;, 3: &#x27;</span>c<span class="string">&#x27; &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 从对象中删除所有 null 和 undefined 的属性</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const obj = &#123; foo: null, bar: undefined, fuzz: 42 &#125;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const removeNullUndefined = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.entries(obj).reduce(</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    (a, [k, v]) =&gt; (v == null ? a : ((a[k] = v), a)),</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    &#123;&#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  );</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const removeNullUndefined1 = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.entries(obj)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .filter(([_, v]) =&gt; v != null)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .reduce((acc, [k, v]) =&gt; (&#123; ...acc, [k]: v &#125;), &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const removeNullUndefined2 = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.fromEntries(Object.entries(obj).filter(([_, v]) =&gt; v != null));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(removeNullUndefined(obj)); // &#123; fuzz: 42 &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(removeNullUndefined1(obj)); // &#123; fuzz: 42 &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(removeNullUndefined2(obj)); // &#123; fuzz: 42 &#125;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 根据对象的属性对其进行排序</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const colorsObj = &#123;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  white: &#x27;</span>#ffffff<span class="string">&#x27;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  black: &#x27;</span>#<span class="number">000000</span><span class="string">&#x27;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  red: &#x27;</span>#ff0000<span class="string">&#x27;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  green: &#x27;</span>#<span class="number">008000</span><span class="string">&#x27;,</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  blue: &#x27;</span>#0000ff<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">&#125;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const colorsSort = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Object.keys(obj)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .sort()</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .reduce((p, c) =&gt; ((p[c] = obj[c]), p), &#123;&#125;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(colorsSort(colorsObj));</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查一个对象是否是Promise</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isPromise = obj =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  !!obj &amp;&amp;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  (typeof obj === &#x27;</span>object<span class="string">&#x27; || typeof obj === &#x27;</span><span class="keyword">function</span><span class="string">&#x27;) &amp;&amp;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  typeof obj.then === &#x27;</span><span class="keyword">function</span><span class="string">&#x27;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 给一个小时添加“am/pm”后缀</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// `h` is an hour number between 0 and 23</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const suffixAmPm = h =&gt; `$&#123;h % 12 === 0 ? 12 : h % 12&#125;$&#123;h &lt; 12 ? &#x27;</span>am<span class="string">&#x27; : &#x27;</span>pm<span class="string">&#x27;&#125;`;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(suffixAmPm(0)); // &#x27;</span>12am<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(suffixAmPm(5)); // &#x27;</span>5am<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(suffixAmPm(12)); // &#x27;</span>12pm<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(suffixAmPm(15)); // &#x27;</span>3pm<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(suffixAmPm(23)); // &#x27;</span>11pm<span class="string">&#x27;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查代码是否在Node.js中运行</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isNode =</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  typeof process !== &#x27;</span><span class="literal">undefined</span><span class="string">&#x27; &amp;&amp;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  process.versions != null &amp;&amp;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  process.versions.node != null;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 检查代码是否在浏览器中运行</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const isBrowser = typeof window === &#x27;</span>object<span class="string">&#x27; &amp;&amp; typeof document === &#x27;</span>object<span class="string">&#x27;;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 生成随机IP地址</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const randomIp = () =&gt;</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">  Array(4)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .fill(0)</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .map((_, i) =&gt; Math.floor(Math.random() * 255) + (i === 0 ? 1 : 0))</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">    .join(&#x27;</span>.<span class="string">&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">console.log(randomIp()); // 175.89.174.131</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">// 使用 Node crypto 模块生成随机字符串</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string">const randomStr = () =&gt; require(&#x27;</span>crypto<span class="string">&#x27;).randomBytes(32).toString(&#x27;</span>hex<span class="string">&#x27;);</span></span></span></span><br><span class="line"><span class="string"><span class="subst"><span class="string"></span></span></span></span><br></pre></td></tr></table></figure>


<h2 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 闭包有3个特性</span></span><br><span class="line"><span class="comment">// (1)、函数嵌套函数</span></span><br><span class="line"><span class="comment">// (2)、闭包就是能够读取其他函数内部变量的函数</span></span><br><span class="line"><span class="comment">// (3)、参数和变量不会被垃圾回收机制回收</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、闭包的本质就是在一个函数内部创建另一个函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> name = <span class="string">&#x27;zs&#x27;</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> name;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> fnn = <span class="title function_">fn</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fnn</span>()); <span class="comment">// zs</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、匿名函数作为fun的返回值被赋值给了f，</span></span><br><span class="line"><span class="comment">// 这个时候相当于f=function() &#123; var n = 0 ...&#125;</span></span><br><span class="line"><span class="comment">// 并且匿名函数内部引用着fun里的变量num，</span></span><br><span class="line"><span class="comment">// 所以变量num无法被销毁</span></span><br><span class="line"><span class="comment">// 而变量n是每次被调用时新创建的，</span></span><br><span class="line"><span class="comment">// 所以每次f执行完后它就把属于自己的变量连同自己一起销毁，</span></span><br><span class="line"><span class="comment">// 于是乎最后就剩下孤零零的num，于是这里就产生了内存销毁的问题</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> num = <span class="number">3</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="number">0</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(++n);</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(++num);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> f = <span class="title function_">fun</span>();</span><br><span class="line"><span class="title function_">f</span>(); <span class="comment">// 1 4</span></span><br><span class="line"><span class="title function_">f</span>(); <span class="comment">// 1 5</span></span><br><span class="line"><span class="comment">// 3、定时器与闭包</span></span><br><span class="line"><span class="comment">// 写一个for循环，让它按顺序打印出当前循环次数</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; ++i) &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">  &#125;, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 按照预期它应该依次输出1 2 3 4 5，而结果它输出了5次5，这是为什么呢？</span></span><br><span class="line"><span class="comment">// 原来由于js是单线程的，所以执行for循环的时候定时器setTimeout被安排到</span></span><br><span class="line"><span class="comment">// 任务队列中排队等待执行，而等待过程中for循环就语句在执行，</span></span><br><span class="line"><span class="comment">// 等到setTimeout可以执行的时候，for循环已经结束，i的值也已经变成5</span></span><br><span class="line"><span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;, <span class="number">0</span>);</span><br><span class="line">i = <span class="number">1</span>;</span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;, <span class="number">0</span>);</span><br><span class="line">i = <span class="number">2</span>;</span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;, <span class="number">0</span>);</span><br><span class="line">i = <span class="number">3</span>;</span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;, <span class="number">0</span>);</span><br><span class="line">i = <span class="number">4</span>;</span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;, <span class="number">0</span>);</span><br><span class="line">i = <span class="number">5</span>;</span><br><span class="line"><span class="comment">// message其实是一个静态字符串，它的值固定为Count为0</span></span><br><span class="line"><span class="comment">// 当我们调用increase或者log时不会改变，</span></span><br><span class="line"><span class="comment">// 所以每次调用log函数，输出的结果总是Count is 0</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">createCounter</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> count = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">increase</span>(<span class="params"></span>) &#123;</span><br><span class="line">    count++;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> message = <span class="string">`Count is <span class="subst">$&#123;count&#125;</span>`</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(message); <span class="comment">// 0</span></span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">log</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// 如果希望log函数及时检查count的值，需要将message移入log</span></span><br><span class="line">    <span class="keyword">let</span> message = <span class="string">`Count is <span class="subst">$&#123;count&#125;</span>`</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(message); <span class="comment">// 3</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> [increase, log];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> [increase, log] = <span class="title function_">createCounter</span>();</span><br><span class="line"><span class="title function_">increase</span>();</span><br><span class="line"><span class="title function_">increase</span>();</span><br><span class="line"><span class="title function_">increase</span>();</span><br><span class="line"><span class="title function_">log</span>();</span><br><span class="line"><span class="comment">// 首先讲讲闭包的定义：</span></span><br><span class="line"><span class="comment">// 在我看来，闭包有三大特点。</span></span><br><span class="line"><span class="comment">// 一是函数嵌套函数，二是外部函数可以访问内部函数的变量，三是参数和变量不会被垃圾回收机制回收。</span></span><br><span class="line"><span class="comment">// 所以简单来说我认为闭包可以理解为是连接函数内部和函数外部的一座桥梁。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 然后讲讲闭包的原理：</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 为什么会形成闭包呢，因为当内部函数被返回至外部并保存时，一定会形成闭包。</span></span><br><span class="line"><span class="comment">// 而关于闭包为什么能访问内部函数的变量，且不会垃圾回收机制回收，是因为闭包会产生原来的作用域链不被释放。</span></span><br><span class="line"><span class="comment">// 我们从JS预编译的角度来讲，可以知道当外部函数执行的前一刻，内部函数被定义，</span></span><br><span class="line"><span class="comment">// 此时他的作用域链和外部函数的作用域链完全相同，都会指向该外部函数的AO（函数上下文）。</span></span><br><span class="line"><span class="comment">// 然后等到外部函数执行结束，原本应被释放的外部函数的AO却因为内部函数被返回至外部且有一个变量进行接收保存，</span></span><br><span class="line"><span class="comment">// 因此该外部函数的AO没有被销毁，还被内部函数的作用域链连接着。所以当我们进行访问内部函数的变量时，</span></span><br><span class="line"><span class="comment">// 若该内部函数查询不到该变量，则它会向外部函数中的AO去寻找，若无则沿着其自身作用域链依次往上级查找。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 闭包的优点：</span></span><br><span class="line"><span class="comment">// 可以将一个变量长期存储在内存中，用于缓存</span></span><br><span class="line"><span class="comment">// 可以避免全局变量的污染</span></span><br><span class="line"><span class="comment">// 加强封装性，实现了对变量的隐藏和封装</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 闭包的缺点：</span></span><br><span class="line"><span class="comment">// 因为函数执行上下文AO执行完后不被释放，所以会导致内存消耗很大，增加了内存消耗量，影响网页性能出现问题</span></span><br><span class="line"><span class="comment">// 而且过度的使用闭包可能会导致内存泄露，或程序加载运行过慢卡顿等问题出现。</span></span><br><span class="line"><span class="comment">// 所以我们可以在退出函数之前，将不使用的局部变量进行删除。</span></span><br><span class="line"><span class="comment">// 私有化变量,封装功能集</span></span><br><span class="line"><span class="comment">// 比如说我们有个应用场景，是对某个属性的值进行增删减查，例如拿一个简单的学生管理系统来说，</span></span><br><span class="line"><span class="comment">// 我们可以对外部函数的变量students进行私有化，在外部访问内部函数的方法改变私有变量students的值</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">myClass</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> students = [];</span><br><span class="line">  <span class="keyword">var</span> operations = &#123;</span><br><span class="line">    <span class="title function_">joinStu</span>(<span class="params">name</span>) &#123;</span><br><span class="line">      students.<span class="title function_">push</span>(name);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">leaveStu</span>(<span class="params">name</span>) &#123;</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; students.<span class="property">length</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">var</span> item = students[i];</span><br><span class="line">        <span class="keyword">if</span> (item === name) &#123;</span><br><span class="line">          students.<span class="title function_">splice</span>(i, <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">findStu</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(students);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> operations;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> class1 = <span class="title function_">myClass</span>();</span><br><span class="line"></span><br><span class="line">class1.<span class="title function_">findStu</span>(); <span class="comment">// []</span></span><br><span class="line">class1.<span class="title function_">joinStu</span>(<span class="string">&#x27;Trist&#x27;</span>);</span><br><span class="line">class1.<span class="title function_">findStu</span>(); <span class="comment">// [&quot;Trist&quot;]</span></span><br><span class="line">class1.<span class="title function_">joinStu</span>(<span class="string">&#x27;张三&#x27;</span>);</span><br><span class="line">class1.<span class="title function_">findStu</span>(); <span class="comment">// [&quot;Trist&quot;, &quot;张三&quot;]</span></span><br><span class="line">class1.<span class="title function_">leaveStu</span>(<span class="string">&#x27;张三&#x27;</span>);</span><br><span class="line">class1.<span class="title function_">findStu</span>(); <span class="comment">// [&quot;Trist&quot;]</span></span><br></pre></td></tr></table></figure>

<h2 id="什么场景适合用New-Map-，而不是用-Object"><a href="#什么场景适合用New-Map-，而不是用-Object" class="headerlink" title="什么场景适合用New Map()，而不是用 Object"></a>什么场景适合用New Map()，而不是用 Object</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、接受任何类型的键 划重点，是任何any！！！</span></span><br><span class="line"><span class="comment">// 除了NaN比较特殊外，</span></span><br><span class="line"><span class="comment">// 其他Map的get方法都是通过对比键名是否相等（===）来获取，不相等则返回undefined</span></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"><span class="keyword">let</span> str = <span class="string">&#x27;today&#x27;</span>,</span><br><span class="line">  num = <span class="number">666</span>,</span><br><span class="line">  keyFn = <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;,</span><br><span class="line">  keySymbol = <span class="title class_">Symbol</span>(<span class="string">&#x27;web&#x27;</span>),</span><br><span class="line">  keyNull = <span class="literal">null</span>,</span><br><span class="line">  keyUndefined = <span class="literal">undefined</span>,</span><br><span class="line">  keyNaN = <span class="title class_">NaN</span>;</span><br><span class="line"></span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;key&#x27;</span>, <span class="string">&#x27;value&#x27;</span>);</span><br><span class="line">map</span><br><span class="line">  .<span class="title function_">set</span>(str, <span class="string">&#x27;tomorrow&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(num, <span class="string">&#x27;前端666&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(keyFn, <span class="string">&#x27;调用函数&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(keySymbol, <span class="string">&#x27;前端&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(keyNull, <span class="string">&#x27;我是null&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(keyUndefined, <span class="string">&#x27;我是undefined&#x27;</span>)</span><br><span class="line">  .<span class="title function_">set</span>(keyNaN, <span class="string">&#x27;我是NaN&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;)); <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(keySymbol)); <span class="comment">// 前端</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(keySymbol === <span class="title class_">Symbol</span>(<span class="string">&#x27;web&#x27;</span>)); <span class="comment">// false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(<span class="title class_">Symbol</span>(<span class="string">&#x27;web&#x27;</span>))); <span class="comment">// undefined</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、比较 Map 和 Object</span></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;key&#x27;</span>, <span class="string">&#x27;value&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(<span class="string">&#x27;key&#x27;</span>)); <span class="comment">// &#x27;value&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj = &#123;&#125;;</span><br><span class="line">obj.<span class="property">key</span> = <span class="string">&#x27;value&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">key</span>); <span class="comment">// &#x27;value&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、键名类型</span></span><br><span class="line"><span class="comment">// Map支持正则作为键名，这在Object是不被允许的直接报错，可后面尝试了一下好像又是可以的</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;&#125;;</span><br><span class="line">obj[<span class="literal">true</span>] = <span class="string">&#x27;Boolean&#x27;</span>;</span><br><span class="line">obj[<span class="number">1</span>] = <span class="string">&#x27;Number&#x27;</span>;</span><br><span class="line">obj[&#123; 前端: <span class="string">&#x27;vue&#x27;</span> &#125;] = <span class="string">&#x27;666&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(obj)); <span class="comment">// [&#x27;1&#x27;, &#x27;true&#x27;, &#x27;[object Object]&#x27;]</span></span><br><span class="line">obj[<span class="regexp">/^1[3456789]\d&#123;9&#125;$/</span>] = <span class="string">&#x27;手机号正则表达式&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(obj)); <span class="comment">// [&#x27;1&#x27;, &#x27;true&#x27;, &#x27;[object Object]&#x27;, &#x27;/^1[3456789]\\d&#123;9&#125;$/&#x27;]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(<span class="number">1</span>, <span class="string">&#x27;value&#x27;</span>).<span class="title function_">set</span>(<span class="literal">true</span>, <span class="string">&#x27;value&#x27;</span>).<span class="title function_">set</span>(&#123; <span class="attr">key</span>: <span class="string">&#x27;value&#x27;</span> &#125;, <span class="string">&#x27;value&#x27;</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">of</span> map.<span class="title function_">keys</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key); <span class="comment">// 1 true &#123;key: &#x27;value&#x27;&#125;</span></span><br><span class="line">&#125;</span><br><span class="line">map.<span class="title function_">set</span>(<span class="regexp">/^1[3456789]\d&#123;9&#125;$/</span>, <span class="string">&#x27;手机号正则表达式&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map); <span class="comment">// &#123;1 =&gt; &#x27;value&#x27;, true =&gt; &#x27;value&#x27;, &#123;key: &#x27;value&#x27;&#125; =&gt; &#x27;value&#x27;, /^1[3456789]\d&#123;9&#125;$/ =&gt; &#x27;手机号正则表达式’&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 4、迭代器</span></span><br><span class="line"><span class="comment">// Map 是可迭代的，可以直接进行迭代，例如forEach循环或者for...of...循环</span></span><br><span class="line"><span class="comment">// 但是对于Object是不能直接迭代但，当你尝试迭代将导致报错</span></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;key1&#x27;</span>, <span class="string">&#x27;value1&#x27;</span>).<span class="title function_">set</span>(<span class="string">&#x27;key2&#x27;</span>, <span class="string">&#x27;value2&#x27;</span>).<span class="title function_">set</span>(<span class="string">&#x27;key3&#x27;</span>, <span class="string">&#x27;value3&#x27;</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> entry <span class="keyword">of</span> map) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(entry); <span class="comment">// [&#x27;key1&#x27;, &#x27;value1&#x27;] [&#x27;key2&#x27;, &#x27;value2&#x27;] [&#x27;key3&#x27;, &#x27;value3&#x27;]</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">key1</span>: <span class="string">&#x27;value1&#x27;</span>,</span><br><span class="line">  <span class="attr">key2</span>: <span class="string">&#x27;value2&#x27;</span>,</span><br><span class="line">  <span class="attr">key3</span>: <span class="string">&#x27;value3&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> entry <span class="keyword">of</span> <span class="title class_">Object</span>.<span class="title function_">entries</span>(obj)) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(entry); <span class="comment">// [&#x27;key1&#x27;, &#x27;value1&#x27;] [&#x27;key2&#x27;, &#x27;value2&#x27;] [&#x27;key3&#x27;, &#x27;value3&#x27;]</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 5、元素顺序和长度</span></span><br><span class="line"><span class="comment">// Map 保持对长度的跟踪，使其能够在0(1)复杂度中进行访问</span></span><br><span class="line"><span class="comment">// Object 想要获得对象的属性长度，需要手动对其进行迭代，使其为0(n)复杂度，属性长度为n</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Map始终保持按插入顺序返回键名</span></span><br><span class="line"><span class="comment">// Object却不是，从ES6开始，String和Symbol键是按顺序保持起来的，但通过隐式转换保持成String的键就是乱序的</span></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;key1&#x27;</span>, <span class="string">&#x27;value1&#x27;</span>).<span class="title function_">set</span>(<span class="string">&#x27;key0&#x27;</span>, <span class="string">&#x27;value0&#x27;</span>).<span class="title function_">set</span>(<span class="string">&#x27;20&#x27;</span>, <span class="string">&#x27;value20&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map, map.<span class="property">size</span>); <span class="comment">// &#123;&#x27;key1&#x27; =&gt; &#x27;value1&#x27;, &#x27;key0&#x27; =&gt; &#x27;value0&#x27;, &#x27;20&#x27; =&gt; &#x27;value20&#x27;&#125; 3</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj = &#123;&#125;;</span><br><span class="line">obj[<span class="string">&#x27;key1&#x27;</span>] = <span class="string">&#x27;value1&#x27;</span>;</span><br><span class="line">obj[<span class="string">&#x27;key0&#x27;</span>] = <span class="string">&#x27;value0&#x27;</span>;</span><br><span class="line">obj[<span class="string">&#x27;20&#x27;</span>] = <span class="string">&#x27;value20&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj, <span class="title class_">Object</span>.<span class="title function_">keys</span>(obj).<span class="property">length</span>); <span class="comment">// &#123;20: &#x27;value20&#x27;, key1: &#x27;value1&#x27;, key0: &#x27;value0&#x27;&#125; 3</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Object/Map 何为最佳实践</span></span><br><span class="line"><span class="comment">// 1、当插入顺序是你解决问题时需要考虑的，并且当前需要使用除String和Symbol以外的键名时，那么Map就是个最佳解决方案</span></span><br><span class="line"><span class="comment">// 2、如果需要遍历键值对（并且需要考虑顺序），还是需要优先考虑Map</span></span><br><span class="line"><span class="comment">// 3、Map在频繁增删键值对的场景下表现更好，性能更高</span></span><br><span class="line"><span class="comment">// 4、再举一个实际的例子，比如有一个自定义字段的用户操作功能，用户可以通过表单自定义字段，</span></span><br><span class="line"><span class="comment">// 那么这时候最好是使用Map，因为object很有可能会破坏原有的对象。</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>


<h2 id="call-apply-bind"><a href="#call-apply-bind" class="headerlink" title="call apply bind"></a>call apply bind</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// JS中有一个关键概念叫做执行上下文，也就是JavaScript 代码被解析和执行时的环境。</span></span><br><span class="line"><span class="comment">// 执行上下文有三种类型：全局执行上下文、函数执行上下文和Eval 函数执行上下文。</span></span><br><span class="line"><span class="comment">// 在执行上下文的创建阶段，会确定当前执行上下文中this指针的指向。</span></span><br><span class="line"><span class="comment">// 而call，apply，bind的作用，就是改变函数执行时的上下文，即改变函数内部的this指向。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// call也是函数原型对象上的一个方法，用于暂时改变函数的this指向</span></span><br><span class="line"><span class="comment">// 会对this指向的对象进行属性的读取，添加，修改，方法的调用</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">showName1</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">id</span> = <span class="number">2</span>;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">func_attr</span> = <span class="string">&#x27;func_attr&#x27;</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">id</span> + <span class="string">&#x27;:&#x27;</span> + <span class="variable language_">this</span>.<span class="property">name</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">id</span>: <span class="number">1</span>, <span class="attr">name</span>: <span class="string">&#x27;yuguang&#x27;</span> &#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(showName1.<span class="title function_">call</span>(obj)); <span class="comment">// 2:yuguang</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj); <span class="comment">// &#123;id: 2, name: &#x27;yuguang&#x27;, func_attr: &#x27;func_attr&#x27;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// call的基本思想，就是将函数暂时绑定到目标对象，然后在目标对象的作用域下执行函数；</span></span><br><span class="line"><span class="comment">// 在函数执行时，函数可以通过this来对对象进行操作。之后，将函数从对象上移除。</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">newCall</span> = <span class="keyword">function</span> (<span class="params">obj</span>) &#123;</span><br><span class="line">  obj.<span class="property">new_func</span> = <span class="variable language_">this</span>; <span class="comment">// 调用newcall的对象是函数foo，this指向函数。现在使obj上有了一个新方法foo</span></span><br><span class="line">  <span class="keyword">let</span> args = [];</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">1</span>; i &lt; <span class="variable language_">arguments</span>.<span class="property">length</span>; i++) args.<span class="title function_">push</span>(<span class="variable language_">arguments</span>[i]);</span><br><span class="line">  <span class="keyword">let</span> result = obj.<span class="title function_">new_func</span>(...args);</span><br><span class="line">  <span class="keyword">delete</span> obj.<span class="property">new_func</span>;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = x;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">attr</span> = y;</span><br><span class="line">  <span class="keyword">return</span> y;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> obj1 = &#123; <span class="attr">name</span>: <span class="string">&#x27;obj1_name&#x27;</span> &#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo.<span class="title function_">newCall</span>(obj1, <span class="string">&#x27;first&#x27;</span>, <span class="string">&#x27;second&#x27;</span>)); <span class="comment">// second</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj1); <span class="comment">// &#123;name: &#x27;first&#x27;, attr: &#x27;second&#x27;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// bind是函数原型对象上的一个方法，用于改变函数的this指向</span></span><br><span class="line"><span class="comment">// 这个方法会返回一个新函数，新函数可以调用他所绑定的对象的属性。</span></span><br><span class="line"><span class="keyword">var</span> name = <span class="string">&#x27;window&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> newThis = &#123; <span class="attr">name</span>: <span class="string">&#x27;newThis&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">var</span> <span class="title function_">showName</span> = (<span class="params">info1, info2</span>) =&gt; <span class="string">`<span class="subst">$&#123;info1&#125;</span>:<span class="subst">$&#123;info2&#125;</span>`</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">showName</span>(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>), <span class="string">&#x27;showName&#x27;</span>);</span><br><span class="line"><span class="comment">// 通过bind改变this指向</span></span><br><span class="line"><span class="keyword">var</span> newShowName = showName.<span class="title function_">bind</span>(newThis, <span class="string">&#x27;hello&#x27;</span>, <span class="string">&#x27;world&#x27;</span>);</span><br><span class="line">showName = <span class="function">(<span class="params">info1, info2</span>) =&gt;</span> <span class="string">&#x27;new_func&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">showName</span>(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>), <span class="string">&#x27;new -- showName&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">newShowName</span>(), <span class="string">&#x27;newShowName&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// fun.call/bind(thisArg, arg1, arg2, ...)</span></span><br><span class="line"><span class="comment">// thisArg：当前调用函数this的指向对象，arg1、arg2：传递的其他参数</span></span><br><span class="line"><span class="comment">// call方法</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;我想喝手磨咖啡&#x27;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(x + y);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> o = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;wei&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 1、call()可以调用函数</span></span><br><span class="line">fn.<span class="title function_">call</span>();</span><br><span class="line"><span class="comment">// 2、call()可以改变这个函数的this指向</span></span><br><span class="line">fn.<span class="title function_">call</span>(o, <span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 3、call的主要作用可以实现继承</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">uname, age, sex</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">uname</span> = uname;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">uname, age, sex</span>) &#123;</span><br><span class="line">  <span class="title class_">People</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>, uname, age, sex);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> person = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;刘德华&#x27;</span>, <span class="number">20</span>, <span class="string">&#x27;男&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(person);</span><br><span class="line"></span><br><span class="line"><span class="comment">//fun.apply(thisArg, [argsArray])</span></span><br><span class="line"><span class="comment">//thisArg: 在fun函数运行时指定的this值，argsArray：传递的值，必须包含在数组里面</span></span><br><span class="line"><span class="comment">//返回值就是函数的返回值，因为它就是调用函数</span></span><br><span class="line"><span class="comment">//1、也是调用函数，第二个可以改变函数内部的this指向</span></span><br><span class="line"><span class="comment">//2、但是他的参数必须是数组(伪数组)</span></span><br><span class="line"><span class="comment">//3、apply的主要应用 比如说可以利用apply借助于数学内置对象求最大值</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn2</span>(<span class="params">arr8</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arr8); <span class="comment">//&#x27;pink&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> o2 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;jin&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line">fn2.<span class="title function_">apply</span>(o2, [<span class="string">&#x27;pink&#x27;</span>]);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr9 = [<span class="number">1</span>, <span class="number">66</span>, <span class="number">3</span>, <span class="number">99</span>, <span class="number">4</span>];</span><br><span class="line"><span class="keyword">var</span> max = <span class="title class_">Math</span>.<span class="property">max</span>.<span class="title function_">apply</span>(<span class="title class_">Math</span>, arr9);</span><br><span class="line"><span class="keyword">var</span> min = <span class="title class_">Math</span>.<span class="property">min</span>.<span class="title function_">apply</span>(<span class="title class_">Math</span>, arr9);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(max, min);</span><br><span class="line"></span><br><span class="line"><span class="comment">//bind() 绑定</span></span><br><span class="line"><span class="comment">//1、不会调用原来的函数，可以改变原来函数内部的this指向</span></span><br><span class="line"><span class="comment">//2、返回的是原函数改变this之后产生的新函数(原函数拷贝)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn3</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a + b); <span class="comment">//3</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> o3 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;tao&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> f3 = fn3.<span class="title function_">bind</span>(o3, <span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line"><span class="title function_">f3</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">//语法：call(fn, obj, ...agrs)</span></span><br><span class="line"><span class="comment">//功能：执行fn，使this为obj，并将后面的n个参数传给fn(功能等同于函数对象的call方法)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">call</span>(<span class="params">Fn, obj, ...args</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (obj === <span class="literal">undefined</span> || obj === <span class="literal">null</span>) obj = globalThis; <span class="comment">//全局对象</span></span><br><span class="line">  obj.<span class="property">temp</span> = <span class="title class_">Fn</span>; <span class="comment">// 这边就是一个函数 function add(a, b) &#123;&#125;</span></span><br><span class="line">  <span class="keyword">let</span> result = obj.<span class="title function_">temp</span>(...args); <span class="comment">//因为args是应该数组形式，所以必须解构 [10, 20] ===&gt; 10 20</span></span><br><span class="line">  <span class="keyword">delete</span> obj.<span class="property">temp</span>; <span class="comment">// 删除 temp 方法</span></span><br><span class="line">  <span class="keyword">return</span> result; <span class="comment">// 返回执行结果</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//声明一个函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, <span class="string">&#x27;this&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> a + b + <span class="variable language_">this</span>.<span class="property">c</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">c</span>: <span class="number">521</span> &#125;; <span class="comment">// 声明一个对象</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">c</span> = <span class="number">1314</span>; <span class="comment">// 添加全局属性</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">call</span>(add, obj, <span class="number">10</span>, <span class="number">20</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">call</span>(add, <span class="literal">null</span>, <span class="number">30</span>, <span class="number">40</span>));</span><br><span class="line"><span class="comment">// 语法：apply(fn, obj, args)</span></span><br><span class="line"><span class="comment">// 功能：执行fn，使this为obj，并将args数组中的元素传给fn(功能等同于函数对象的apply方法)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">apply</span>(<span class="params">Fn, obj, args</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (obj === <span class="literal">undefined</span> || obj === <span class="literal">null</span>) obj = globalThis; <span class="comment">// 全局对象</span></span><br><span class="line">  obj.<span class="property">temp</span> = <span class="title class_">Fn</span>; <span class="comment">// 为 obj 添加临时的方法</span></span><br><span class="line">  <span class="keyword">let</span> result = obj.<span class="title function_">temp</span>(...args); <span class="comment">// 调用 temp 方法</span></span><br><span class="line">  <span class="keyword">delete</span> obj.<span class="property">temp</span>; <span class="comment">// 删除 temp 方法</span></span><br><span class="line">  <span class="keyword">return</span> result; <span class="comment">// 返回执行结果</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 声明一个函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, <span class="string">&#x27;this&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> a + b + <span class="variable language_">this</span>.<span class="property">c</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">c</span>: <span class="number">521</span> &#125;; <span class="comment">// 声明一个对象</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">c</span> = <span class="number">1314</span>; <span class="comment">// 添加全局属性</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">apply</span>(add, obj, [<span class="number">10</span>, <span class="number">20</span>]));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">apply</span>(add, <span class="literal">null</span>, [<span class="number">30</span>, <span class="number">40</span>]));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 语法：bind(fn, obj, ...args)</span></span><br><span class="line"><span class="comment">// 功能：给fn绑定this为obj，并指定参数为后面的n个参数(功能等同于函数对象的bind方法)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bind</span>(<span class="params">Fn, obj, ...args</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function">(<span class="params">...args2</span>) =&gt;</span> <span class="title function_">call</span>(<span class="title class_">Fn</span>, obj, ...args, ...args2); <span class="comment">// 执行call函数</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">call</span>(<span class="params">Fn, obj, ...args</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (obj === <span class="literal">undefined</span> || obj === <span class="literal">null</span>) obj = globalThis;</span><br><span class="line">  obj.<span class="property">temp</span> = <span class="title class_">Fn</span>;</span><br><span class="line">  <span class="keyword">let</span> result = obj.<span class="title function_">temp</span>(...args);</span><br><span class="line">  <span class="keyword">delete</span> obj.<span class="property">temp</span>;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//声明一个函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, <span class="string">&#x27;this&#x27;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>, <span class="string">&#x27;arguments&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> a + b + <span class="variable language_">this</span>.<span class="property">c</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">c</span>: <span class="number">521</span> &#125;; <span class="comment">// 声明一个对象</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">c</span> = <span class="number">1314</span>; <span class="comment">// 添加全局属性</span></span><br><span class="line"><span class="keyword">let</span> fn = <span class="title function_">bind</span>(add, obj, <span class="number">10</span>, <span class="number">20</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn</span>());</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> fn2 = <span class="title function_">bind</span>(add, obj);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn2</span>(<span class="number">10</span>, <span class="number">20</span>));</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> fn3 = add.<span class="title function_">bind</span>(obj, <span class="number">10</span>, <span class="number">20</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn3</span>(<span class="number">30</span>, <span class="number">40</span>));</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> fn4 = <span class="title function_">bind</span>(add, obj, <span class="number">10</span>, <span class="number">20</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn4</span>(<span class="number">30</span>, <span class="number">50</span>));</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="柯里化函数"><a href="#柯里化函数" class="headerlink" title="柯里化函数"></a>柯里化函数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 柯里化函数调用其实会一直返回函数，直到最后一个参数传入以后才会执行</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 柯里化 curry</span></span><br><span class="line"><span class="comment">// 函数柯里化就是我们给一个函数传入一部分参数，此时就会返回一个函数来接收剩余的参数</span></span><br><span class="line"><span class="comment">// 高阶函数例子: Array.prototype.map、setTimeout(() =&gt; &#123; &#125;, 0)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 没有柯里化实现的案例</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">a, b, c</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b + c;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)); <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 将其转为柯里化的案例</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum1</span>(<span class="params">a</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">b</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">c</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> a + b + c;</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum1</span>(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>)); <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 上述代码简写成</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">sum2</span> = a =&gt; <span class="function"><span class="params">b</span> =&gt;</span> <span class="function"><span class="params">c</span> =&gt;</span> a + b + c;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum2</span>(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>)); <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数柯里化的好处</span></span><br><span class="line"><span class="comment">// 当我们处理函数时，希望函数功能尽可能单一</span></span><br><span class="line"><span class="comment">// 如希望第一个参数+2，第二个参数*2，第三个参数**2，最后再相加，此时就可以使用函数的柯里化</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params">a</span>) &#123;</span><br><span class="line">  a += <span class="number">2</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">b</span>) &#123;</span><br><span class="line">    b *= <span class="number">2</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">c</span>) &#123;</span><br><span class="line">      c **= <span class="number">2</span>;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(a, b, c, <span class="string">&#x27;a b c&#x27;</span>);</span><br><span class="line">      <span class="keyword">return</span> a + b + c;</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fun</span>(<span class="number">2</span>)(<span class="number">3</span>)(<span class="number">4</span>)); <span class="comment">// 26</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 自动柯里化</span></span><br><span class="line"><span class="comment">// 1、这里的fn.length获取的是函数传入参数的长度</span></span><br><span class="line"><span class="comment">// 2、这里使用递归的思想</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">myCurried</span>(<span class="params">fn</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> <span class="title function_">curry</span>(<span class="params">...args1</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (args1.<span class="property">length</span> &gt;= fn.<span class="property">length</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> fn.<span class="title function_">call</span>(<span class="literal">null</span>, ...args1);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">...args2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> curry.<span class="title function_">apply</span>(<span class="literal">null</span>, [...args1, ...args2]);</span><br><span class="line">      &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">mySum</span>(<span class="params">a, b, c, d, e</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b + c + d + e;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> resFun = <span class="title function_">myCurried</span>(mySum);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">resFun</span>(<span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>)(<span class="number">1</span>)(<span class="number">23</span>)); <span class="comment">// 32</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 延迟调用</span></span><br><span class="line"><span class="comment">// js中的bind方法其实底层原理也是应用了柯里化技术，来看看bind方法的简易版代码</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bind</span>(<span class="params">ctx, ...args</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">apply</span>(ctx, args); <span class="comment">// 这里的this指的就是调用bind方法的那个函数</span></span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 说明：从上面bind方法可以看出，调用bind方法后它只是改变了内部this指向，</span></span><br><span class="line"><span class="comment">// 并返回了一个函数，并没有立即执行该函数，如果想要得到结果，需要再次调用bind方法返回的那个函数才行，</span></span><br><span class="line"><span class="comment">// 所以这点也就说明了柯里化函数有延迟调用的作用</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// curry的一些性能问题</span></span><br><span class="line"><span class="comment">// 1、存取arguments对象通常要比存取命名参数要慢一点</span></span><br><span class="line"><span class="comment">// 2、一些老版本的浏览器在arguments.length的实现上是相当慢的</span></span><br><span class="line"><span class="comment">// 3、使用fn.apply(...)和fn.call(...)通常比直接调用fn(...)稍微慢点</span></span><br><span class="line"><span class="comment">// 4、创建大量嵌套作用域和闭包函数会带来花销，无论是在内存还是速度上</span></span><br><span class="line"><span class="comment">// 当然了，其实在大部分应用中，主要的性能瓶颈是在操作DOM节点上</span></span><br><span class="line"><span class="comment">// 这些curry的性能损耗基本是可以忽略不计的，所以curry是可以直接放心的使用</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="arguments"><a href="#arguments" class="headerlink" title="arguments"></a>arguments</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 当我们不确定有多少个参数传递的时候，可以用 arguments 来获取。</span></span><br><span class="line"><span class="comment">// 在 JavaScript 中，arguments 实际上它是当前函数的一个内置对象。</span></span><br><span class="line"><span class="comment">// 所有函数都内置了一个 arguments 对象，arguments 对象中存储了传递的所有实参。</span></span><br><span class="line"><span class="comment">// arguments展示形式是一个伪数组，因此可以进行遍历。伪数组具有以下特点：</span></span><br><span class="line"><span class="comment">// 具有 length 属性</span></span><br><span class="line"><span class="comment">// 按索引方式储存数据</span></span><br><span class="line"><span class="comment">// 不具有数组的 push, pop 等方法</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 其实Javascript并没有重载函数的功能，但是Arguments对象能够模拟重载。</span></span><br><span class="line"><span class="comment">// Javascrip中每个函数都会有一个Arguments对象实例arguments，</span></span><br><span class="line"><span class="comment">// 它引用着函数的实参，可以用数组下标的方式&quot;[]&quot;引用arguments的元素。</span></span><br><span class="line"><span class="comment">// arguments.length为函数实参个数，arguments.callee引用函数自身。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 特性：</span></span><br><span class="line"><span class="comment">// 1.arguments对象和Function是分不开的。</span></span><br><span class="line"><span class="comment">// 2.因为arguments这个对象不能显式创建。</span></span><br><span class="line"><span class="comment">// 3.arguments对象只有函数开始时才可用。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用方法：</span></span><br><span class="line"><span class="comment">// 虽然arguments对象并不是一个数组，但是访问单个参数的方式与访问数组元素的方式相同</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用场景</span></span><br><span class="line"><span class="comment">// 利用函数求任意个数的最大值</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">maxValue</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> max = <span class="variable language_">arguments</span>[<span class="number">0</span>];</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="variable language_">arguments</span>.<span class="property">length</span>; i++) &#123;</span><br><span class="line">    <span class="keyword">if</span> (max &lt; <span class="variable language_">arguments</span>[i]) max = <span class="variable language_">arguments</span>[i];</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">maxValue</span>(<span class="number">2</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">9</span>)); <span class="comment">// 9</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 在实际开发，建议不要再使用arguments了，请使用ES6的解构语法</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">maxValue2</span>(<span class="params">...data</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> max = data[<span class="number">0</span>];</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; data.<span class="property">length</span>; i++) &#123;</span><br><span class="line">    <span class="keyword">if</span> (max &lt; data[i]) max = data[i];</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">maxValue2</span>(<span class="number">2</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">9</span>)); <span class="comment">// 9</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// callee是arguments对象的属性。在函数体内，它指向当前正在执行的函数。</span></span><br><span class="line"><span class="comment">// ECMAScript 5 禁止在严格模式中使用 arguments.callee()。</span></span><br><span class="line"><span class="comment">// 当一个函数必须调用自身的时候，假如它是函数表达式则给它命名，或者使用函数声明，避免使用 arguments.callee()</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用场景:</span></span><br><span class="line"><span class="comment">// 使用arguments.callee最常见的情景是当我们要创造一个递归函数的时候：</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">factorial</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num &lt;= <span class="number">1</span> ? <span class="number">1</span> : num * <span class="variable language_">arguments</span>.<span class="title function_">callee</span>(num - <span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">factorial</span>(<span class="number">4</span>)); <span class="comment">// 24</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 但是如果代码是在严格模式下开发，使用&quot;use strict&quot;;则会出现报错</span></span><br><span class="line"><span class="comment">// 在严格模式下不能通过脚本访问arguments.callee,访问这个属性会报错，那么可以使用命名函数表达式来达到相同的结果：</span></span><br><span class="line">(<span class="string">&#x27;use strict&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> factorial2 = <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num &lt;= <span class="number">1</span> ? <span class="number">1</span> : num * <span class="variable language_">arguments</span>.<span class="title function_">callee</span>(num - <span class="number">1</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">factorial2</span>(<span class="number">4</span>)); <span class="comment">// 24</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 知识扩展：</span></span><br><span class="line"><span class="comment">// 当使用arguments进行函数传递时，有一些需要注意的点。</span></span><br><span class="line"><span class="comment">// 这里有2个需要注意的点。fn函数里面的this的指向：</span></span><br><span class="line"><span class="comment">// 1.第一个值为10，执行的是method里面的第一行&quot;fn()&quot;, 这里this指向的window。所以输出的值为最外层定义的length。</span></span><br><span class="line"><span class="comment">// 2.第二个值为2，执行的是method里面的第二行&quot;arguments[0]()&quot;（arguments[0]() =&gt; fn() ），</span></span><br><span class="line"><span class="comment">// 这里this执行的是arguments这个对象, 所以输出值为arguments的长度</span></span><br><span class="line"><span class="keyword">var</span> length = <span class="number">10</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">length</span>, <span class="string">&#x27;length&#x27;</span>); <span class="comment">// 第一次 10、第二次 2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="title function_">method</span>(<span class="params">fn</span>) &#123;</span><br><span class="line">    <span class="title function_">fn</span>();</span><br><span class="line">    <span class="variable language_">arguments</span>[<span class="number">0</span>]();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">method</span>(fn, <span class="number">1</span>)); <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>

<h2 id="浅拷贝-深拷贝"><a href="#浅拷贝-深拷贝" class="headerlink" title="浅拷贝 深拷贝"></a>浅拷贝 深拷贝</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//浅拷贝只拷贝一层，更深层次对象级别的只拷贝引用</span></span><br><span class="line"><span class="comment">//深拷贝拷贝多层，每一级别的数据都会拷贝</span></span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">id</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;wei&#x27;</span>,</span><br><span class="line">  <span class="attr">msg</span>: &#123;</span><br><span class="line">    <span class="attr">age</span>: <span class="number">18</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">color</span>: [<span class="string">&#x27;pink&#x27;</span>, <span class="string">&#x27;red&#x27;</span>]</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> o2 = &#123;&#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> k <span class="keyword">in</span> obj2) &#123;</span><br><span class="line">  <span class="comment">//这个方法属于浅拷贝</span></span><br><span class="line">  <span class="comment">//k是属性名 obj[k]属性值</span></span><br><span class="line">  o2[k] = obj2[k];</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(o2);</span><br><span class="line">o2.<span class="property">msg</span>.<span class="property">age</span> = <span class="number">10</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2);</span><br><span class="line"></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">assign</span>(o2, obj2); <span class="comment">//浅拷贝只是拷贝了msg里的地址</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(o2);</span><br><span class="line">o2.<span class="property">msg</span>.<span class="property">age</span> = <span class="number">20</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 封装函数 深拷贝</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">deepCopy</span>(<span class="params">newobj, oldobj</span>) &#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> k <span class="keyword">in</span> oldobj) &#123;</span><br><span class="line">    <span class="comment">//判断我们的属性值属于哪种数据类型</span></span><br><span class="line">    <span class="comment">//1、获取属性值 oldobj[k]</span></span><br><span class="line">    <span class="keyword">var</span> item = oldobj[k];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (item <span class="keyword">instanceof</span> <span class="title class_">Array</span>) &#123;</span><br><span class="line">      <span class="comment">//2、判断这个值是否是数组</span></span><br><span class="line">      newobj[k] = [];</span><br><span class="line">      <span class="title function_">deepCopy</span>(newobj[k], item);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (item <span class="keyword">instanceof</span> <span class="title class_">Object</span>) &#123;</span><br><span class="line">      <span class="comment">//3、判断这个值是否是对象</span></span><br><span class="line">      newobj[k] = &#123;&#125;;</span><br><span class="line">      <span class="title function_">deepCopy</span>(newobj[k], item);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">//4、属于简单数据类型</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">deepCopy</span>(o2, obj2);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(o2);</span><br><span class="line">o2.<span class="property">msg</span>.<span class="property">age</span> = <span class="number">40</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2);</span><br><span class="line"></span><br></pre></td></tr></table></figure>


<h2 id="函数的定义方式"><a href="#函数的定义方式" class="headerlink" title="函数的定义方式"></a>函数的定义方式</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//函数的定义方式</span></span><br><span class="line"><span class="comment">// 1、自定义函数(命名函数)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、函数表达式(匿名函数)</span></span><br><span class="line"><span class="keyword">var</span> fun = <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、利用new Function(&#x27;参数1&#x27;, &#x27;参数2&#x27;, &#x27;函数体&#x27;); 已经很少用了</span></span><br><span class="line"><span class="keyword">var</span> f = <span class="keyword">new</span> <span class="title class_">Function</span>(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;console.log(a + b)&#x27;</span>);</span><br><span class="line"><span class="title function_">f</span>(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4、所有函数都是Function的实例(对象)</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">dir</span>(f); <span class="comment">//anonymous匿名</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 5、函数也属于对象</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(f <span class="keyword">instanceof</span> <span class="title class_">Object</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//总结：函数的调用方式</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、普通函数 this指向window</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;普通函数的this：&#x27;</span> + <span class="variable language_">this</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">window</span>.<span class="title function_">fn</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、对象的方法 this指向的是对象o</span></span><br><span class="line"><span class="keyword">var</span> o = &#123;</span><br><span class="line">  <span class="attr">sayHi</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;对象的方法的this：&#x27;</span> + <span class="variable language_">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">o.<span class="title function_">sayHi</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、构造函数 this指向ldh这个实例对象 原型对象里面的this指向的也是ldh这个实例对象</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Star</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sing</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;;</span><br><span class="line"><span class="keyword">var</span> ldh = <span class="keyword">new</span> <span class="title class_">Star</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4、绑定事件函数 this指向的是函数的调用者 btn这个按钮对象</span></span><br><span class="line">btn[<span class="number">1</span>].<span class="property">onclick</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;绑定事件函数的this：&#x27;</span> + <span class="variable language_">this</span>);</span><br><span class="line">&#125;; <span class="comment">// 点击了按钮就可以调用这个函数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 5、定时器函数 this指向的是window</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="built_in">setInterval</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;定时器的this：&#x27;</span> + <span class="variable language_">this</span>);</span><br><span class="line">&#125;, <span class="number">1000</span>); <span class="comment">// 这个函数是定时器自动1秒钟调用一次</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 6立即执行函数 this指向的是window</span></span><br><span class="line">(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;立即执行函数&#x27;</span>);</span><br><span class="line">&#125;)(); <span class="comment">// 自动调用，相对于普通函数就不需要自己手动调用</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 开启严格模式 &#x27;use strict&#x27;;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 高阶函数是对其他函数进行操作的函数，它接收函数作为参数或者将函数作为返回值输出</span></span><br><span class="line"><span class="comment">// 函数可以作为参数传递</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params">a, b, callback</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a + b);</span><br><span class="line">  callback &amp;&amp; <span class="title function_">callback</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fn</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;我是最后调用的&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="创建类和生成类"><a href="#创建类和生成类" class="headerlink" title="创建类和生成类"></a>创建类和生成类</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在ES6中类没有变量提升，所有必须先定义类，才能通过类实例化对象</span></span><br><span class="line"><span class="comment">//1、创建class 创建一个明星类</span></span><br><span class="line"><span class="keyword">var</span> that;</span><br><span class="line"><span class="keyword">var</span> _that;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Star</span> &#123;</span><br><span class="line">  <span class="comment">//该函数可以接收传递过来的参数，同时返回实例对象</span></span><br><span class="line">  <span class="comment">//只要new生成实例时，就会自动调用这个函数，如果我们不写这个函数，类也会自动生成这个函数</span></span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">uname, age</span>) &#123;</span><br><span class="line">    <span class="comment">//constructor里面的this指向的是 创建的实例对象</span></span><br><span class="line">    that = <span class="variable language_">this</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>); <span class="comment">//</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">uname</span> = uname;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">    <span class="comment">// this.sing();</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">btn</span> = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;button&#x27;</span>);</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">btn</span>.<span class="property">onclick</span> = <span class="variable language_">this</span>.<span class="property">sing</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//共有的方法，类里面的共有的属性和方法一定要加this使用</span></span><br><span class="line">  <span class="title function_">sing</span>(<span class="params">song</span>) &#123;</span><br><span class="line">    <span class="comment">//这个sing方法里面的this指向的是btn这个按钮，因为这个按钮调用了这个函数</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">uname</span> + song); <span class="comment">//因为这个this指向的是btn这个按钮，所以这里就会输出undefined</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(that.<span class="property">uname</span>); <span class="comment">//that里面存储的是constructor里面的this</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">dance</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//这个dance里面的this 指向的是实例对象 ldh 因为ldh调用了这个函数</span></span><br><span class="line">    _that = <span class="variable language_">this</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//2、利用类创建对象 new</span></span><br><span class="line"><span class="comment">//(1)我们类里面的所有函数不需要写function</span></span><br><span class="line"><span class="comment">//(2)多个函数之间不需要添加逗号分割</span></span><br><span class="line"><span class="keyword">var</span> ldh = <span class="keyword">new</span> <span class="title class_">Star</span>(<span class="string">&#x27;刘德华&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(that === ldh); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh);</span><br><span class="line">ldh.<span class="title function_">sing</span>(<span class="string">&#x27;冰雨&#x27;</span>);</span><br><span class="line">ldh.<span class="title function_">dance</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(_that === ldh); <span class="comment">//true</span></span><br><span class="line"><span class="keyword">var</span> zxy = <span class="keyword">new</span> <span class="title class_">Star</span>(<span class="string">&#x27;张学友&#x27;</span>, <span class="number">20</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(zxy);</span><br><span class="line">zxy.<span class="title function_">sing</span>(<span class="string">&#x27;心如刀割&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//类的继承 extends</span></span><br><span class="line"><span class="comment">//1、继承中，如果实例化子类输出一个方法，先看子类有没有这个方法，如果有就先执行子类的</span></span><br><span class="line"><span class="comment">//2、如果子类里面没有这个方法，就去查找父类中有没有这个方法，如果有，就去执行父类的这个方法(就近原则)</span></span><br><span class="line"><span class="comment">//super关键字 用于访问和调用对象父类上的函数。可以调用父类中的构造函数，也可以调用父类的普通函数</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Father</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line">  <span class="title function_">money</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;一百万&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">say</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;我是父亲&#x27;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Son</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Father</span> &#123;</span><br><span class="line">  <span class="title function_">say</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//console.log(&#x27;我是儿子&#x27;)</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">super</span>.<span class="title function_">say</span>() + <span class="string">&#x27;的儿子&#x27;</span>); <span class="comment">//super.say()就是调用父类中的普通函数say()</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> son = <span class="keyword">new</span> <span class="title class_">Son</span>();</span><br><span class="line">son.<span class="title function_">money</span>();</span><br><span class="line">son.<span class="title function_">say</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Sums</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = x;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">y</span> = y;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">sums</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">x</span> + <span class="variable language_">this</span>.<span class="property">y</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//子类继承父类加法方法，同时扩展减法方法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Sum</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Sums</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">    <span class="comment">//利用super调用父类的构造函数，super必须在子类this之前调用</span></span><br><span class="line">    <span class="variable language_">super</span>(x, y); <span class="comment">//调用了父类中的构造函数</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = x;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">y</span> = y;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">substract</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">x</span> - <span class="variable language_">this</span>.<span class="property">y</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> sum = <span class="keyword">new</span> <span class="title class_">Sum</span>(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">sum.<span class="title function_">sums</span>();</span><br><span class="line">sum.<span class="title function_">substract</span>();</span><br></pre></td></tr></table></figure>


<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// this指向案例 21-30</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 21、外层this与内层this</span></span><br><span class="line"><span class="comment">// 如果使用call、bind等修改了外层函数的this，那内层函数的this会受影响吗</span></span><br><span class="line"><span class="comment">// 注意区别箭头函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>);</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> obj = &#123; <span class="attr">a</span>: <span class="number">1</span> &#125;;</span><br><span class="line"><span class="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line">foo.<span class="title function_">call</span>(obj)(); <span class="comment">// 1   2</span></span><br><span class="line"><span class="comment">// 第一层函数foo通过call将this指向obj，打印1</span></span><br><span class="line"><span class="comment">// 第二层函数为匿名函数，默认绑定，打印2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 22、对象中的call</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="string">&#x27;obj&#x27;</span>,</span><br><span class="line">  <span class="attr">foo</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;foo&#x27;</span>, <span class="variable language_">this</span>.<span class="property">a</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> a = <span class="string">&#x27;window&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> obj2 = &#123; <span class="attr">a</span>: <span class="string">&#x27;obj2&#x27;</span> &#125;;</span><br><span class="line">obj.<span class="title function_">foo</span>()(); <span class="comment">// &#x27;foo&#x27; obj   window</span></span><br><span class="line">obj.<span class="property">foo</span>.<span class="title function_">call</span>(obj2)(); <span class="comment">// &#x27;foo&#x27; obj2   window</span></span><br><span class="line">obj.<span class="title function_">foo</span>().<span class="title function_">call</span>(obj2); <span class="comment">// &#x27;foo&#x27; obj   obj2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 23、带参数的call</span></span><br><span class="line"><span class="comment">// 显示绑定一开始讲的时候，就谈过call/apply存在传参差异，</span></span><br><span class="line"><span class="comment">// 那咱们就来传一下参数，看看传完参数的this会是怎么的美妙</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">foo</span>: <span class="keyword">function</span> (<span class="params">b</span>) &#123;</span><br><span class="line">    b = b || <span class="variable language_">this</span>.<span class="property">a</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">c</span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span> + b + c);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">var</span> obj2 = &#123; <span class="attr">a</span>: <span class="number">3</span> &#125;;</span><br><span class="line">obj.<span class="title function_">foo</span>(a).<span class="title function_">call</span>(obj2, <span class="number">1</span>); <span class="comment">// 3 + 2 + 1 = 6</span></span><br><span class="line"><span class="comment">// obj.foo(a) 这边我们可以推出 b = 2</span></span><br><span class="line"><span class="comment">// 接下来由于return出来的匿名函数指向了obj2，可以推出 a = 3，c = 1</span></span><br><span class="line">obj.<span class="property">foo</span>.<span class="title function_">call</span>(obj2)(<span class="number">1</span>); <span class="comment">// 2 + 3 + 1 = 6</span></span><br><span class="line"><span class="comment">// obj.foo.call(obj2) obj.foo的this指向obj2，未传入参数</span></span><br><span class="line"><span class="comment">// b = this.a = obj2.a = 3；返回匿名函数fn</span></span><br><span class="line"><span class="comment">// 匿名函数fn(1) 可得 c = 1，由于默认绑定，this指向Window，则 a = 2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 24、显示绑定拓展</span></span><br><span class="line"><span class="comment">// apply求数组最值</span></span><br><span class="line"><span class="comment">// JavaScript中没有给数组提供类似max和min函数，</span></span><br><span class="line"><span class="comment">// 只提供了Max.max/min， 用于求多个数的最值，</span></span><br><span class="line"><span class="comment">// 所以可以借助apply方法，直接传递给Math.max/min</span></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">33</span>, <span class="number">4</span>, <span class="number">52</span>, <span class="number">17</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Math</span>.<span class="property">max</span>.<span class="title function_">apply</span>(<span class="title class_">Math</span>, arr)); <span class="comment">// 52</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Math</span>.<span class="property">min</span>.<span class="title function_">apply</span>(<span class="title class_">Math</span>, arr)); <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 类数组转为数组</span></span><br><span class="line"><span class="comment">// ES6未发布之前，没有Array.from方法可以将类数组转为数组，</span></span><br><span class="line"><span class="comment">// 采用Array.prototype.slice.call(arguments)或</span></span><br><span class="line"><span class="comment">// [].slice.call(arguments)将类数组转化为数组</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 数组高阶函数</span></span><br><span class="line"><span class="comment">// 日常编码中，我们会经常用到forEach、map等，</span></span><br><span class="line"><span class="comment">// 但这些数组高阶方法，它们还有第二个参数thisArg，</span></span><br><span class="line"><span class="comment">// 每一个回调函数都是显式绑定在thisArg上的</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123; <span class="attr">a</span>: <span class="number">10</span> &#125;;</span><br><span class="line"><span class="keyword">const</span> array = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>];</span><br><span class="line">array.<span class="title function_">forEach</span>(<span class="keyword">function</span> (<span class="params">val, key</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;key&#125;</span>: <span class="subst">$&#123;val&#125;</span> --- <span class="subst">$&#123;<span class="variable language_">this</span>.a&#125;</span>`</span>);</span><br><span class="line">&#125;, obj);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 25、new绑定</span></span><br><span class="line"><span class="comment">// 使用new来构建函数，会执行如下四部操作：</span></span><br><span class="line"><span class="comment">// 1、创建一个空的简单JavaScript对象(即&#123;&#125;)</span></span><br><span class="line"><span class="comment">// 2、为步骤1新创建的对象添加属性__proto__,</span></span><br><span class="line"><span class="comment">// 将该属性链接至构造函数的原型对象；</span></span><br><span class="line"><span class="comment">// 3、将步骤1新创建的对象作为this的上下文；</span></span><br><span class="line"><span class="comment">// 如果该函数没有返回对象，则返回this</span></span><br><span class="line"><span class="comment">// 通过new来调用构造函数，会生成一个新对象，</span></span><br><span class="line"><span class="comment">// 并且把这个新对象绑定为调用函数的this</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">User</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">introduce</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">howOld</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">age</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> name = <span class="string">&#x27;Tom&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> age = <span class="number">18</span>;</span><br><span class="line"><span class="keyword">var</span> zc = <span class="keyword">new</span> <span class="title class_">User</span>(<span class="string">&#x27;zc&#x27;</span>, <span class="number">24</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(zc.<span class="property">name</span>); <span class="comment">// zc</span></span><br><span class="line">zc.<span class="title function_">introduce</span>(); <span class="comment">// zc</span></span><br><span class="line"><span class="comment">// zc是new创建的实例，this指向zc，打印zc</span></span><br><span class="line">zc.<span class="title function_">howOld</span>()(); <span class="comment">// 18</span></span><br><span class="line"><span class="comment">// zc.howOld()返回一个匿名函数，匿名函数为默认绑定</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 26、new界的天王山 （太难了太难了）</span></span><br><span class="line"><span class="comment">// 部分优先级如下：</span></span><br><span class="line"><span class="comment">// new(带参数列表) = 成员访问 = 函数调用 &gt; new(不带参数)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  getName = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">1</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Foo</span>.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">2</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title class_">Foo</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">3</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> getName = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">4</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getName</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">5</span>); <span class="comment">// 在运行了Foo()后，5变为1了</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 预编译</span></span><br><span class="line"><span class="comment">// GO = &#123;</span></span><br><span class="line"><span class="comment">//   Foo: fn(Foo),</span></span><br><span class="line"><span class="comment">//   getName: function getName() &#123;</span></span><br><span class="line"><span class="comment">//     console.log(5);</span></span><br><span class="line"><span class="comment">//   &#125;,</span></span><br><span class="line"><span class="comment">// &#125;;</span></span><br><span class="line"><span class="title class_">Foo</span>.<span class="title function_">getName</span>(); <span class="comment">// 2</span></span><br><span class="line"><span class="title function_">getName</span>(); <span class="comment">// 4</span></span><br><span class="line"><span class="title class_">Foo</span>().<span class="title function_">getName</span>(); <span class="comment">// 1 相当于window.getName()</span></span><br><span class="line"><span class="comment">// Foo()执行完后</span></span><br><span class="line"><span class="comment">// 修改全局GO的getName为function()&#123;console.log(1)&#125;</span></span><br><span class="line"><span class="comment">// Foo为默认绑定，this -&gt; window</span></span><br><span class="line"><span class="comment">// return window</span></span><br><span class="line"><span class="title function_">getName</span>(); <span class="comment">// 1</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Foo</span>.<span class="title function_">getName</span>(); <span class="comment">// 2</span></span><br><span class="line"><span class="comment">// 首先从左往右看：new Foo属于不带参数列表的new(优先级19)，</span></span><br><span class="line"><span class="comment">// Foo.getName属于成员访问(优先级20)，</span></span><br><span class="line"><span class="comment">// getName()属于函数调用(优先级20)，同样优先级遵循从左往右执行</span></span><br><span class="line"><span class="comment">// 此时原表达式变为new(Foo.getName)()，其为带参数列表(优先级20)，</span></span><br><span class="line"><span class="comment">// (Foo.getName)()属于函数调用(优先级20)，从左往右执行</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Foo</span>().<span class="title function_">getName</span>(); <span class="comment">// 3</span></span><br><span class="line"><span class="comment">// new Foo()</span></span><br><span class="line"><span class="comment">// Foo.prototype.getName</span></span><br><span class="line"><span class="keyword">new</span> <span class="keyword">new</span> <span class="title class_">Foo</span>().<span class="title function_">getName</span>(); <span class="comment">// 3</span></span><br><span class="line"><span class="comment">// new(new Foo().getName)()</span></span><br><span class="line"><span class="comment">// Foo.prototype.getName()</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;--------------------&#x27;</span>);</span><br><span class="line">foo1 = <span class="keyword">new</span> <span class="title class_">Foo</span>.<span class="title function_">getName</span>(); <span class="comment">// 2</span></span><br><span class="line">foo2 = <span class="keyword">new</span> <span class="keyword">new</span> <span class="title class_">Foo</span>().<span class="title function_">getName</span>(); <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo1.<span class="property">constructor</span>); <span class="comment">// f() &#123;console.log(2)&#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo2.<span class="property">constructor</span>); <span class="comment">// f() &#123;console.log(3)&#125;</span></span><br><span class="line"><span class="comment">// new Foo.getName()和new new Foo().getName() 二者区别</span></span><br><span class="line"><span class="comment">// new Foo.getName()的构造函数是Foo.getName</span></span><br><span class="line"><span class="comment">// new new Foo().getName()的构造函数为Foo.prototype.getName</span></span><br><span class="line"><span class="comment">// 27、指向函数定义时的this而非执行时：JavaScript是静态作用域,</span></span><br><span class="line"><span class="comment">// 就是函数定义之后，作用域就定死了，跟他执行时的地方无关</span></span><br><span class="line"><span class="comment">// 对象方法使用箭头函数</span></span><br><span class="line">name = <span class="string">&#x27;tom&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;zc&#x27;</span>,</span><br><span class="line">  <span class="attr">intro</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;My name is &#x27;</span> + <span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="title function_">intro</span>(); <span class="comment">// tom</span></span><br><span class="line"><span class="comment">// 箭头函数的this通过作用域链查到，</span></span><br><span class="line"><span class="comment">// intro函数的上层作用域为window</span></span><br><span class="line"><span class="comment">// 28、箭头函数与普通函数比较</span></span><br><span class="line">name = <span class="string">&#x27;tom&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;zc&#x27;</span>,</span><br><span class="line">  <span class="attr">intro</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;=&gt;&#x27;</span>, <span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">intro2</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;普通函数&#x27;</span>, <span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="title function_">intro</span>()(); <span class="comment">// zc</span></span><br><span class="line">obj.<span class="title function_">intro2</span>()(); <span class="comment">// tom</span></span><br><span class="line"><span class="comment">// 29、箭头函数与普通函数的嵌套</span></span><br><span class="line">name = <span class="string">&#x27;window&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> obj1 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;obj1&#x27;</span>,</span><br><span class="line">  <span class="attr">intro</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;obj2&#x27;</span>,</span><br><span class="line">  <span class="attr">intro</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> obj3 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;obj3&#x27;</span>,</span><br><span class="line">  <span class="attr">intro</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">obj1.<span class="title function_">intro</span>()(); <span class="comment">// obj1 obj1</span></span><br><span class="line">obj2.<span class="title function_">intro</span>()(); <span class="comment">// window window</span></span><br><span class="line">obj3.<span class="title function_">intro</span>()(); <span class="comment">// window window</span></span><br><span class="line"><span class="comment">// 30、new碰上箭头函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">User</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">intro</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">howOld</span> = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">age</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> name = <span class="string">&#x27;Tom&#x27;</span>,</span><br><span class="line">  aeg = <span class="number">18</span>;</span><br><span class="line"><span class="keyword">var</span> zc = <span class="keyword">new</span> <span class="title class_">User</span>(<span class="string">&#x27;zc&#x27;</span>, <span class="number">24</span>);</span><br><span class="line">zc.<span class="title function_">intro</span>(); <span class="comment">// zc</span></span><br><span class="line">zc.<span class="title function_">howOld</span>(); <span class="comment">// 24</span></span><br><span class="line"><span class="comment">// howOld为箭头函数this由外层决定，且指向函数定义时的this，</span></span><br><span class="line"><span class="comment">// 外层作用域为User，this指向zc</span></span><br></pre></td></tr></table></figure>

<h2 id="基本类型和引用类型"><a href="#基本类型和引用类型" class="headerlink" title="基本类型和引用类型"></a>基本类型和引用类型</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 对引用类型来说，变量就好像一个名字，它的引用值就好像是一个实体，多个变量可以指向同一个实体</span></span><br><span class="line"><span class="comment">// jt是你，tt也是你，一个大名一个小名，但都是你。</span></span><br><span class="line"><span class="comment">// 我说jt，帮我拿个苹果，其实tt也在拿苹果，因为都是同一个人</span></span><br><span class="line"><span class="keyword">var</span> o = &#123; <span class="attr">a</span>: <span class="number">1</span> &#125;;</span><br><span class="line"><span class="keyword">var</span> array = [o];</span><br><span class="line">o.<span class="property">a</span> = <span class="number">2</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr[<span class="number">0</span>]);</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="事件"><a href="#事件" class="headerlink" title="事件"></a>事件</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// mouseenter和mouseleave不存在事件冒泡，但是mouseout和mouseover存在事件冒泡。</span></span><br><span class="line"><span class="comment">// 当在其子元素中来回切换时，mouseenter和mouseleave是不触发的，但是mouseout和mouseover是触发的。</span></span><br><span class="line"><span class="comment">// 一般这种移入移出的效果，用enter和leave来做比较方便</span></span><br></pre></td></tr></table></figure>

<h2 id="javascript-中：’true’-true-为什么返回false"><a href="#javascript-中：’true’-true-为什么返回false" class="headerlink" title="javascript 中：’true’ &#x3D;&#x3D; true; 为什么返回false"></a>javascript 中：’true’ &#x3D;&#x3D; true; 为什么返回false</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// javascript 中：&#x27;true&#x27; == true; 为什么返回false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.5.7 相等操作符</span></span><br><span class="line"><span class="comment">// 在转换不同的数据类型时，相等和不相等操作符遵循下列基本规则：</span></span><br><span class="line"><span class="comment">// 1. 如果有一个操作数是布尔值，则在比较相等性之前先将其转换为数值——false转换为0，而true转换为1；</span></span><br><span class="line"><span class="comment">// 2. 如果一个操作数是字符串，另一个操作数是数值，在比较相等性之前先将字符串转换为数值；</span></span><br><span class="line"><span class="comment">// 3. 如果一个操作数是对象，另一个操作数不是，则调用对象的valueOf()方法，用得到的基本类型值按照前面的规则进行比较；</span></span><br><span class="line"><span class="comment">// 首先 &#x27;true&#x27; == true 符合规则 1，这样就转化成了对 &#x27;true&#x27; == 1 进行求值</span></span><br><span class="line"><span class="comment">// 此时表达式符合规则 2</span></span><br><span class="line"><span class="comment">// 2. 如果一个操作数是字符串，另一个操作数是数值，在比较相等性之前先将字符串转换为数值；</span></span><br><span class="line"><span class="comment">// 也就是说需要将 &#x27;true&#x27; 转换成数值之后，再与数字 1 进行比较。把 &#x27;true&#x27; 转换成数值是使用 Number 函数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.4.5 Number 类型</span></span><br><span class="line"><span class="comment">// Number()函数的转换规则如下。</span></span><br><span class="line"><span class="comment">// 1. 如果是Boolean值，true和false将分别被转换为1和0。</span></span><br><span class="line"><span class="comment">// 2. 如果是数字值，只是简单的传入和返回。</span></span><br><span class="line"><span class="comment">// 3. 如果是null值，返回0。</span></span><br><span class="line"><span class="comment">// 4. 如果是undefined，返回NaN。</span></span><br><span class="line"><span class="comment">// 5. 如果是字符串，遵循下列规则：</span></span><br><span class="line"><span class="comment">// 5.1 如果字符串中只包含数字（包括前面带加号或负号的情况），则将其转换为十进制数值，</span></span><br><span class="line"><span class="comment">// 即&quot;1&quot;会变成1，&quot;123&quot;会变成123，而&quot;011&quot;会变成11（注意：前导的零被忽略了）；</span></span><br><span class="line"><span class="comment">// 5.2 如果字符串中包含有效的浮点格式，如&quot;1.1&quot;，则将其转换为对应的浮点数值（同样，也会忽略前导零）；</span></span><br><span class="line"><span class="comment">// 5.3 如果字符串中包含有效的十六进制格式，例如&quot;0xf&quot;，则将其转换为相同大小的十进制整数值；</span></span><br><span class="line"><span class="comment">// 5.4 如果字符串是空的（不包含任何字符），则将其转换为0；</span></span><br><span class="line"><span class="comment">// 5.5 如果字符串中包含除上述格式之外的字符，则将其转换为NaN</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 按照规则 5 和规则 5.5，Number(&#x27;true&#x27;) 的值为 NaN，也就是说现在的问题变成了对 NaN == 1 进行求值。</span></span><br><span class="line"><span class="comment">// 还是在这一节中，提到了</span></span><br><span class="line"><span class="comment">// 其次，NaN与任何值都不相等，包括NaN本身。</span></span><br><span class="line"><span class="comment">// 也就是说 NaN == 1 的值是 false。</span></span><br><span class="line"><span class="comment">// 最后捋一遍，&#x27;true&#x27; == true --&gt; &#x27;true&#x27; == 1 --&gt; NaN == 1 --&gt; false。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// JavaScript 的 == 判断符隐含着各种隐式转换，对于这种设计上的坑，</span></span><br><span class="line"><span class="comment">// 最好的避免方式就是不使用，没有必要为语言的糟粕买单。</span></span><br><span class="line"><span class="comment">// 实际上，几乎所有地方使用全等操作符 === 都更加有必要，如果分不清楚什么时候可以用相等操作符 ==，</span></span><br><span class="line"><span class="comment">// 那就直接记住结论，统一使用全等操作符 ===</span></span><br></pre></td></tr></table></figure>

<h2 id="我们可以让1-1等于任何数"><a href="#我们可以让1-1等于任何数" class="headerlink" title="我们可以让1+1等于任何数"></a>我们可以让1+1等于任何数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> a = &#123;</span><br><span class="line">  [<span class="title class_">Symbol</span>.<span class="property">replace</span>](a) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;tttb&#x27;</span> + a;</span><br><span class="line">  &#125;,</span><br><span class="line">  [<span class="title class_">Symbol</span>()]: <span class="number">1</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// a.toString = function () &#123;</span></span><br><span class="line"><span class="comment">// return &#x27;bba&#x27;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;aaaa&#x27;</span>.<span class="title function_">replace</span>(a));</span><br><span class="line"><span class="keyword">const</span> a = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&#x27;aaa&#x27;</span>);</span><br><span class="line"><span class="keyword">let</span> num = <span class="number">3</span>;</span><br><span class="line">a.<span class="property">valueOf</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(num, <span class="string">&#x27;xxx&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> num++;</span><br><span class="line">&#125;;</span><br><span class="line">a.<span class="property">toString</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;xxx&#x27;</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">if</span> (a == <span class="number">3</span> &amp;&amp; a == <span class="number">4</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;a&#125;</span>1`</span>); <span class="comment">// 模版字符串会隐式调用toString方法</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a + <span class="number">1</span>); <span class="comment">// 加号默认调用的valueOf方法</span></span><br><span class="line"><span class="keyword">const</span> a = <span class="keyword">new</span> <span class="title class_">Number</span>(<span class="number">3</span>);</span><br><span class="line"><span class="keyword">let</span> num = <span class="number">3</span>;</span><br><span class="line">a.<span class="property">valueOf</span> = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(num, <span class="string">&#x27;xxx&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> num++;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">if</span> (a == <span class="number">3</span> &amp;&amp; a == <span class="number">4</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">1</span> === <span class="keyword">new</span> <span class="title class_">Number</span>(<span class="number">1</span>));</span><br><span class="line"><span class="keyword">const</span> a = <span class="keyword">new</span> <span class="title class_">Number</span>(<span class="number">3</span>);</span><br><span class="line"><span class="keyword">let</span> num = <span class="number">3</span>;</span><br><span class="line">a.<span class="property">valueOf</span> = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(num, <span class="string">&#x27;xxx&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> num++;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">if</span> (a === <span class="number">3</span> &amp;&amp; a === <span class="number">4</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a, <span class="string">&#x27;sucess&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</span><br><span class="line"><span class="keyword">let</span> i = <span class="number">0</span>;</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(<span class="variable language_">window</span>, <span class="string">&#x27;a&#x27;</span>, &#123;</span><br><span class="line">  <span class="title function_">get</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> arr[i++];</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a, <span class="string">&#x27;a&#x27;</span>);</span><br><span class="line"><span class="keyword">if</span> (<span class="variable language_">window</span>.<span class="property">a</span> === <span class="number">2</span> &amp;&amp; <span class="variable language_">window</span>.<span class="property">a</span> === <span class="number">3</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;success&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// const obj = &#123; a: 2 &#125;</span></span><br><span class="line"><span class="comment">// Object.defineProperty(obj, &quot;a&quot;, &#123;</span></span><br><span class="line"><span class="comment">// get() &#123;</span></span><br><span class="line"><span class="comment">// if (obj.a &lt; 4) &#123;</span></span><br><span class="line"><span class="comment">// return obj.a++</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// &#125;)</span></span><br><span class="line"><span class="comment">// if (obj.a === 2 &amp;&amp; obj.a === 3) &#123;</span></span><br><span class="line"><span class="comment">// console.log(&#x27;success&#x27;)</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br></pre></td></tr></table></figure>


<h2 id="for-in-和-for-of"><a href="#for-in-和-for-of" class="headerlink" title="for in 和 for of"></a>for in 和 for of</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// for in 是ES5的语法标准，而for of则是ES6语法标准。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、循环数组</span></span><br><span class="line"><span class="comment">// for in 和 for of 都可以循环数组，for in 输出的是数组的index下标，且为String类型，而for of 输出的是数组的每一项的值。</span></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">in</span> arr) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key, <span class="keyword">typeof</span> key); <span class="comment">// 输出 0,1,2,3 String类型</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">of</span> arr) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key); <span class="comment">// 输出 1,2,3,4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、循环对象</span></span><br><span class="line"><span class="comment">// for in 可以遍历对象，for of 不能遍历对象，只能遍历带有iterator接口的，例如Set,Map,String,Array</span></span><br><span class="line"><span class="keyword">const</span> object = &#123; <span class="attr">name</span>: <span class="string">&#x27;lx&#x27;</span>, <span class="attr">age</span>: <span class="number">23</span> &#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">in</span> object) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key, object[key]); <span class="comment">// 输出 name,lx; age,23</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">of</span> object) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key); <span class="comment">// 报错 Uncaught TypeError: object is not iterable</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、数组对象</span></span><br><span class="line"><span class="keyword">const</span> list = [&#123; <span class="attr">name</span>: <span class="string">&#x27;lx&#x27;</span> &#125;, &#123; <span class="attr">age</span>: <span class="number">23</span> &#125;];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> val <span class="keyword">of</span> list) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(val); <span class="comment">// 输出&#123; name: &#x27;lx&#x27; &#125;, &#123; age: 23 &#125;</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">in</span> val) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(val[key]); <span class="comment">// 输出 lx,23</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4、是否会遍历原型链上定义的属性名和方法名</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// for in 遍历时可以遍历到当前数组的所有属性名和方法名,</span></span><br><span class="line"><span class="comment">// 包括其原型链上定义的属性名和方法名。</span></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>];</span><br><span class="line">arr.<span class="property">name</span> = <span class="string">&#x27;arr&#x27;</span>;</span><br><span class="line">arr.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">name</span>;</span><br><span class="line">&#125;;</span><br><span class="line">arr.<span class="property">__proto__</span>.<span class="property">constructor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHello</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line">&#125;;</span><br><span class="line">arr.<span class="property">__proto__</span>.<span class="property">constructor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">parentName</span> = <span class="string">&#x27;say uncle&#x27;</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">in</span> arr) &#123;</span><br><span class="line">  <span class="keyword">if</span> (arr.<span class="title function_">hasOwnProperty</span>(i)) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;ownProperty&#x27;</span>, i);</span><br><span class="line">    <span class="comment">// &#x27;0&#x27;, &#x27;1&#x27;, &#x27;2&#x27;, &#x27;name&#x27;, &#x27;getName&#x27;</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;not ownProperty&#x27;</span>, i);</span><br><span class="line">    <span class="comment">// &#x27;sayHello&#x27;, &#x27;parentName&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 而使用for of遍历时则不会遍历原型链上的属性和方法</span></span><br><span class="line"><span class="comment">// 且不会遍历定义在数组上的属性和方法。</span></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>];</span><br><span class="line">arr.<span class="property">name</span> = <span class="string">&#x27;arr&#x27;</span>;</span><br><span class="line">arr.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">name</span>;</span><br><span class="line">&#125;;</span><br><span class="line">arr.<span class="property">__proto__</span>.<span class="property">constructor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHello</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line">&#125;;</span><br><span class="line">arr.<span class="property">__proto__</span>.<span class="property">constructor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">parentName</span> = <span class="string">&#x27;say uncle&#x27;</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">of</span> arr) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">  <span class="comment">// &#x27;a&#x27;, &#x27;b&#x27;, &#x27;c&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 使用for in遍历对象会遍历对象原型链的方法名和属性名,</span></span><br><span class="line"><span class="comment">// for in 循环实际是为循环可枚举(enumerable)对象而设计的</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;uncle&#x27;</span>,</span><br><span class="line">  <span class="attr">gender</span>: <span class="string">&#x27;male&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">12</span></span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="property">hobby</span> = <span class="string">&#x27;coding&#x27;</span>;</span><br><span class="line">obj.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">name</span>;</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="property">__proto__</span>.<span class="property">constructor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHello</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">  <span class="keyword">if</span> (obj.<span class="title function_">hasOwnProperty</span>(i)) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;ownProperty&#x27;</span>, i);</span><br><span class="line">    <span class="comment">// name, gender, age, hobby, getName</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;not ownProperty&#x27;</span>, i);</span><br><span class="line">    <span class="comment">// sayHello</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 而使用 for of 遍历对象则会报错</span></span><br><span class="line"><span class="comment">// for (let i of obj) &#123;</span></span><br><span class="line"><span class="comment">// console.log(i)</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// error Uncaught TypeError: obj is not iterable</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 这是为什么呢？</span></span><br><span class="line"><span class="comment">// 这是因为能够被for of正常遍历的数据类型都需要实现一个遍历器Iterator。</span></span><br><span class="line"><span class="comment">// 而数组、字符串、Set、Map结构，早就内置好了Iterator（迭代器），</span></span><br><span class="line"><span class="comment">// 它们的原型中都有一个Symbol.iterator方法，而Object对象并没有实现这个接口，使得它无法被for of遍历。</span></span><br><span class="line"><span class="comment">// 我们可以通过为Object实现一个Iterator来使Object可以使用正常for of遍历</span></span><br><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>[<span class="title class_">Symbol</span>.<span class="property">iterator</span>] = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> _this = <span class="variable language_">this</span>;</span><br><span class="line">  <span class="keyword">let</span> index = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">let</span> length = <span class="title class_">Object</span>.<span class="title function_">keys</span>(_this).<span class="property">length</span>;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">next</span>: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">let</span> value = _this[<span class="title class_">Object</span>.<span class="title function_">keys</span>(_this)[index]];</span><br><span class="line">      <span class="keyword">let</span> done = index &gt;= length;</span><br><span class="line">      index++;</span><br><span class="line">      <span class="keyword">return</span> &#123; value, done &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i <span class="keyword">of</span> obj) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 总结：for in适合遍历对象，for of适合遍历数组。for in遍历的是数组的索引，对象的属性，以及原型链上的属性。</span></span><br></pre></td></tr></table></figure>

<h2 id="封装replaceAll-方法"><a href="#封装replaceAll-方法" class="headerlink" title="封装replaceAll()方法"></a>封装replaceAll()方法</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">String</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">replaceAll</span> = <span class="keyword">function</span>(<span class="params">s1, s2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">replace</span>(<span class="keyword">new</span> <span class="title class_">RegExp</span>(s1, <span class="string">&quot;gm&quot;</span>), s2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="toFixed不是采用传统意义上的四舍五入法，而是银行家算法"><a href="#toFixed不是采用传统意义上的四舍五入法，而是银行家算法" class="headerlink" title="toFixed不是采用传统意义上的四舍五入法，而是银行家算法"></a>toFixed不是采用传统意义上的四舍五入法，而是银行家算法</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// toFixed不是采用传统意义上的四舍五入法，而是银行家算法。</span></span><br><span class="line"><span class="comment">// 所以在进行精度算法时，最好在后端计算，而且toFixed方法在不同的浏览器呈现的效果不同</span></span><br><span class="line"><span class="comment">// 银行家算法即：“四舍六入五成双”，当舍掉位是5时，要根据5前一位来判断是否舍入。</span></span><br><span class="line"><span class="comment">// 当5前一位是奇数：舍5入1；当5前一位是偶数：舍5不进。（0为偶数）</span></span><br><span class="line"><span class="comment">// (但同时发现：在chrome种，并不完全遵循所谓的银行家算法，所以在进行金额的换算时，</span></span><br><span class="line"><span class="comment">// 应尽量避免使用toFixed()方法，同时它与后台java等语言的银行家舍入精度不同，可能造成接口验证失败)</span></span><br><span class="line"><span class="comment">// 该方法是标准的四舍五入，使用方法：Math.round(Number);</span></span><br><span class="line"><span class="comment">// 如果想实现四舍五入的方法，建议重写toFixed()方法。</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1.335</span>,</span><br><span class="line">  b = <span class="number">1.345</span>,</span><br><span class="line">  c = <span class="number">1.355</span>,</span><br><span class="line">  d = <span class="number">1.365</span>,</span><br><span class="line">  e = <span class="number">1.375</span>,</span><br><span class="line">  f = <span class="number">1.385</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;a&#x27;</span>, a.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;b&#x27;</span>, b.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;c&#x27;</span>, c.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;d&#x27;</span>, d.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;e&#x27;</span>, e.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;f&#x27;</span>, e.<span class="title function_">toFixed</span>(<span class="number">2</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 小数点四舍五入的方法</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">decimalRound</span>(<span class="params">number, precision</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="title class_">Math</span>.<span class="title function_">round</span>(+number + <span class="string">&#x27;e&#x27;</span> + precision) / <span class="title class_">Math</span>.<span class="title function_">pow</span>(<span class="number">10</span>, precision);</span><br><span class="line">  <span class="comment">//return Number(Math.round(+number + &#x27;e&#x27; + precision) + &#x27;e-&#x27; + precision);</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">decimalRound</span>(<span class="number">1.005</span>, <span class="number">2</span>)); <span class="comment">// 1.01</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">decimalRound</span>(<span class="number">3.35</span>, <span class="number">1</span>)); <span class="comment">// 3.5</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">decimalRound</span>(-<span class="number">3.45345755</span>, <span class="number">6</span>)); <span class="comment">// -3.453458</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以配合input框的@blur来达到输入完之后失去焦点自动往后补0</span></span><br><span class="line"><span class="comment">/**格式化金额*/</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">formatMoney</span>(<span class="params">money, digit</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (money == <span class="literal">null</span> || money == <span class="string">&#x27;&#x27;</span>) <span class="keyword">return</span>;</span><br><span class="line">  <span class="keyword">if</span> (!<span class="regexp">/\./</span>.<span class="title function_">test</span>(money)) &#123;</span><br><span class="line">    <span class="keyword">let</span> zero = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; digit; i++) &#123;</span><br><span class="line">      zero += <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    money += <span class="string">&#x27;.&#x27;</span> + zero;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">let</span> arrayNum = money.<span class="title function_">split</span>(<span class="string">&#x27;.&#x27;</span>);</span><br><span class="line">    <span class="keyword">if</span> (arrayNum[<span class="number">1</span>] != <span class="string">&#x27;&#x27;</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (arrayNum[<span class="number">1</span>].<span class="property">length</span> &lt;= digit) &#123;</span><br><span class="line">        <span class="keyword">let</span> zero = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">        <span class="keyword">let</span> times = digit - arrayNum[<span class="number">1</span>].<span class="property">length</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; times; i++) &#123;</span><br><span class="line">          zero += <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        money += zero;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        money = <span class="keyword">new</span> <span class="title class_">Number</span>(money);</span><br><span class="line">        money = money.<span class="title function_">toFixed</span>(digit);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> money;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="构造函数和原型"><a href="#构造函数和原型" class="headerlink" title="构造函数和原型"></a>构造函数和原型</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、利用new Object() 创建对象</span></span><br><span class="line"><span class="keyword">var</span> obj1 = <span class="keyword">new</span> <span class="title class_">Object</span>();</span><br><span class="line"><span class="comment">// 2、利用对象字面量创建对象</span></span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、利用构造函数创建对象</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Star</span>(<span class="params">uname, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">uname</span> = uname;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="comment">// this.sing = function() &#123;</span></span><br><span class="line">  <span class="comment">//     console.log(&#x27;我会唱歌&#x27;);</span></span><br><span class="line">  <span class="comment">// &#125;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 一般情况下，我们的公共属性定义到构造函数里面，公共的方法我们放到原型对象身上</span></span><br><span class="line"><span class="comment">// 把那些不变的方法，直接定义到prototype对象上，这样所有对象的实例就可以共享这些方法了</span></span><br><span class="line"><span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sing</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;我会唱歌&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 很多情况下，我们需要手动的利用constructor这个属性指回原来的构造函数</span></span><br><span class="line"><span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span> = &#123;</span><br><span class="line">  <span class="comment">// 如果我们修改了原来的原型对象，给原型对象赋值的是一个对象，则必须手动的利用constructor指回原来的构造函数</span></span><br><span class="line">  <span class="attr">constructor</span>: <span class="title class_">Star</span>,</span><br><span class="line">  <span class="attr">sing</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;我会唱歌&#x27;</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">movie</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;我会演电影&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> ldh = <span class="keyword">new</span> <span class="title class_">Star</span>(<span class="string">&#x27;刘德华&#x27;</span>, <span class="number">19</span>);</span><br><span class="line"><span class="keyword">var</span> zxy = <span class="keyword">new</span> <span class="title class_">Star</span>(<span class="string">&#x27;张学友&#x27;</span>, <span class="number">20</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh); <span class="comment">// 对象身上系统直接添加一个__proto__指向我们构造函数的原型对象prototype</span></span><br><span class="line"><span class="comment">// 方法的查找规则：首先先看ldh对象身上是否有sing方法，如果有就执行这个对象上的sing</span></span><br><span class="line"><span class="comment">// 如果没有sing这个方法，因为有__proto__的存在，就去构造函数原型对象prototype身上去查找sing这个方法</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">__proto__</span> === <span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//Object</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">__proto__</span>); <span class="comment">//Object</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Star</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">constructor</span>); <span class="comment">//Star</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">__proto__</span>.<span class="property">constructor</span>); <span class="comment">//Star</span></span><br><span class="line"><span class="comment">// 因为使用构造函数会开辟一个新的内存空间 false，当构造方法在原型对象中时 true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">sing</span> === zxy.<span class="property">sing</span>); <span class="comment">//true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员</span></span><br><span class="line"><span class="comment">// 实例成员只能通过实例化的对象来访问</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">uname</span>);</span><br><span class="line">ldh.<span class="title function_">sing</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Star</span>.<span class="property">uname</span>); <span class="comment">// 不可以通过构造函数来访问实例对象 undefined</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、静态成员 在构造函数本身上添加的成员 sex就是静态成员</span></span><br><span class="line"><span class="title class_">Star</span>.<span class="property">sex</span> = <span class="string">&#x27;男&#x27;</span>;</span><br><span class="line"><span class="comment">// 静态成员只能通过构造函数来访问</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Star</span>.<span class="property">sex</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ldh.<span class="property">sex</span>); <span class="comment">// 不能通过对象来访问 undefined</span></span><br></pre></td></tr></table></figure>

<h2 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 语法：/正则表达式主体/修饰符（可选）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通常用于两个字符串方法 : search() 和 replace()。</span></span><br><span class="line"><span class="comment">// search() 方法用于检索字符串中指定的子字符串，或检索与正则表达式相匹配的子字符串，并返回子串的起始位置。</span></span><br><span class="line"><span class="comment">// replace() 方法用于在字符串中用一些字符串替换另一些字符串，或替换一个与正则表达式匹配的子串。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 修饰符：</span></span><br><span class="line"><span class="comment">//     i：执行对大小不敏感匹配</span></span><br><span class="line"><span class="comment">//     g：执行全局匹配（查找所有匹配而非在找到第一个匹配后停止）</span></span><br><span class="line"><span class="comment">//     m：执行多行匹配</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、利用Regexp对象来创建 正则表达式</span></span><br><span class="line"><span class="keyword">var</span> regexp = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="regexp">/123/</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(regexp); <span class="comment">// /123/</span></span><br><span class="line"><span class="comment">// 2、利用字面量创建 正则表达式</span></span><br><span class="line"><span class="keyword">var</span> rg = <span class="regexp">/123/</span>;</span><br><span class="line"><span class="comment">// 3、test方法用来检测字符串是否符合正则表达式要求的规范</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rg.<span class="title function_">test</span>(<span class="number">123</span>), rg.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), rg.<span class="title function_">test</span>(<span class="string">&#x27;123&#x27;</span>)); <span class="comment">//true false true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 边界符 ^ (表示匹配行首的文本，以谁开始)，</span></span><br><span class="line"><span class="comment">//        $ (表示匹配行尾的文本，以谁结束)</span></span><br><span class="line"><span class="keyword">var</span> rgg = <span class="regexp">/abc/</span>; <span class="comment">//正则表达式里面不需要加引号，不管是数字型还是字符串型</span></span><br><span class="line"><span class="comment">// /abc/ 只要包含abc这个字符串整体返回的都是true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rgg.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), rgg.<span class="title function_">test</span>(<span class="string">&#x27;abcd&#x27;</span>)); <span class="comment">// true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rgg.<span class="title function_">test</span>(<span class="string">&#x27;aabcd&#x27;</span>), rgg.<span class="title function_">test</span>(<span class="string">&#x27;aabdc&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg = <span class="regexp">/^abc/</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), reg.<span class="title function_">test</span>(<span class="string">&#x27;abcd&#x27;</span>)); <span class="comment">// true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg.<span class="title function_">test</span>(<span class="string">&#x27;aabcd&#x27;</span>), reg.<span class="title function_">test</span>(<span class="string">&#x27;aabdc&#x27;</span>)); <span class="comment">// false false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg1 = <span class="regexp">/^abc$/</span>; <span class="comment">// 精确匹配，要求必须是 abc 字符串才符合规范</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg1.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), reg1.<span class="title function_">test</span>(<span class="string">&#x27;abcd&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg1.<span class="title function_">test</span>(<span class="string">&#x27;aabcd&#x27;</span>), reg1.<span class="title function_">test</span>(<span class="string">&#x27;aabdc&#x27;</span>), reg1.<span class="title function_">test</span>(<span class="string">&#x27;abcabc&#x27;</span>)); <span class="comment">//false false false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 字符类：[] 表示有一系列字符可供选择，只要匹配其中一个就可以了</span></span><br><span class="line"><span class="keyword">var</span> reg2 = <span class="regexp">/[abc]/</span>; <span class="comment">// 只要包含有a或者包含有b或者包含有c都返回为true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg2.<span class="title function_">test</span>(<span class="string">&#x27;andy&#x27;</span>), reg2.<span class="title function_">test</span>(<span class="string">&#x27;baby&#x27;</span>)); <span class="comment">// true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg2.<span class="title function_">test</span>(<span class="string">&#x27;background&#x27;</span>), reg2.<span class="title function_">test</span>(<span class="string">&#x27;wei&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg3 = <span class="regexp">/^[abc]$/</span>; <span class="comment">// 三选一 只有是a或者是b或者是c这三个字母才返回true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg3.<span class="title function_">test</span>(<span class="string">&#x27;a&#x27;</span>), reg3.<span class="title function_">test</span>(<span class="string">&#x27;aaa&#x27;</span>), reg3.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>)); <span class="comment">// true false false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg4 = <span class="regexp">/^[a-z]$/</span>; <span class="comment">// 26个英文小写字母，任何一个小写字母返回true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg4.<span class="title function_">test</span>(<span class="string">&#x27;w&#x27;</span>), reg4.<span class="title function_">test</span>(<span class="string">&#x27;1&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg4.<span class="title function_">test</span>(<span class="number">1</span>), reg4.<span class="title function_">test</span>(<span class="string">&#x27;A&#x27;</span>)); <span class="comment">// false false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg5 = <span class="regexp">/^[a-zA-Z]$/</span>; <span class="comment">// 26个英文字母，任何一个(大写、小写)字母返回true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg5.<span class="title function_">test</span>(<span class="string">&#x27;m&#x27;</span>), reg5.<span class="title function_">test</span>(<span class="string">&#x27;M&#x27;</span>)); <span class="comment">// true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg6 = <span class="regexp">/^[a-zA-Z0-9_-]$/</span>; <span class="comment">// 字符组合</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg6.<span class="title function_">test</span>(<span class="string">&#x27;-&#x27;</span>), reg6.<span class="title function_">test</span>(<span class="string">&#x27;_&#x27;</span>)); <span class="comment">// true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg6.<span class="title function_">test</span>(<span class="string">&#x27;8&#x27;</span>), reg6.<span class="title function_">test</span>(<span class="string">&#x27;?&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg7 = <span class="regexp">/^[^a-zA-Z0-9_-]$/</span>; <span class="comment">// 如果中括号里面有^表示取反的意思，千万不能和边界符^混淆</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg7.<span class="title function_">test</span>(<span class="string">&#x27;_&#x27;</span>), reg7.<span class="title function_">test</span>(<span class="string">&#x27;8&#x27;</span>), reg7.<span class="title function_">test</span>(<span class="string">&#x27;?&#x27;</span>)); <span class="comment">// false false true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 量词符：用来设定某个模式出现的次数，也就是让下面的a这个字符重复多少次</span></span><br><span class="line"><span class="keyword">var</span> reg8 = <span class="regexp">/^a*$/</span>; <span class="comment">// * 相当于 &gt;=0 可以出现0次或者很多次</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg8.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg8.<span class="title function_">test</span>(<span class="string">&#x27;a&#x27;</span>), reg8.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>)); <span class="comment">// true true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg9 = <span class="regexp">/^a+$/</span>; <span class="comment">// + 相当于 &gt;=1 可以出现1次或者很多次</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg9.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg9.<span class="title function_">test</span>(<span class="string">&#x27;a&#x27;</span>), reg9.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>)); <span class="comment">// false true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg10 = <span class="regexp">/^a?$/</span>; <span class="comment">// ? 相当于 1 || 0</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg10.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg10.<span class="title function_">test</span>(<span class="string">&#x27;a&#x27;</span>), reg10.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>)); <span class="comment">// true true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg11 = <span class="regexp">/^a&#123;3&#125;$/</span>; <span class="comment">// 就是重复3次</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg11.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg11.<span class="title function_">test</span>(<span class="string">&#x27;aaa&#x27;</span>), reg11.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>)); <span class="comment">//false true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg12 = <span class="regexp">/^a&#123;3,&#125;$/</span>; <span class="comment">// 大于等于3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg12.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg12.<span class="title function_">test</span>(<span class="string">&#x27;aaa&#x27;</span>), reg12.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>)); <span class="comment">// false true true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg13 = <span class="regexp">/^a&#123;3,6&#125;$/</span>; <span class="comment">// 大于等于3，并且小于等于6</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg13.<span class="title function_">test</span>(<span class="string">&#x27;&#x27;</span>), reg13.<span class="title function_">test</span>(<span class="string">&#x27;aaa&#x27;</span>)); <span class="comment">// false true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg13.<span class="title function_">test</span>(<span class="string">&#x27;aaaa&#x27;</span>), reg13.<span class="title function_">test</span>(<span class="string">&#x27;aaaaaaa&#x27;</span>)); <span class="comment">// true false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//量词是设定某个模式出现的次数</span></span><br><span class="line"><span class="keyword">var</span> reg14 = <span class="regexp">/^[a-zA-Z0-9_-]&#123;6,16&#125;$/</span>; <span class="comment">//这样就可以输入6到16位中括号里出现的字符和数字了</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> input = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> span = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;span&#x27;</span>);</span><br><span class="line">input.<span class="title function_">addEventListener</span>(<span class="string">&#x27;blur&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (reg14.<span class="title function_">test</span>(<span class="variable language_">this</span>.<span class="property">value</span>)) &#123;</span><br><span class="line">    span.<span class="property">className</span> = <span class="string">&#x27;right&#x27;</span>;</span><br><span class="line">    span.<span class="property">innerHTML</span> = <span class="string">&#x27;用户名格式输入正确&#x27;</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;正确的&#x27;</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    span.<span class="property">className</span> = <span class="string">&#x27;wrong&#x27;</span>;</span><br><span class="line">    span.<span class="property">innerHTML</span> = <span class="string">&#x27;用户名格式输入错误&#x27;</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;错误的&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//中括号 字符集合 匹配方括号中的任意字符</span></span><br><span class="line"><span class="comment">//大括号 量词符 里面表示重复次数</span></span><br><span class="line"><span class="comment">//小括号 表示优先级</span></span><br><span class="line"><span class="keyword">var</span> reg15 = <span class="regexp">/^abc&#123;3&#125;$/</span>; <span class="comment">// 它只是让c重复3次</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg15.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), reg15.<span class="title function_">test</span>(<span class="string">&#x27;abcabcabc&#x27;</span>)); <span class="comment">// false false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg15.<span class="title function_">test</span>(<span class="string">&#x27;abccc&#x27;</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;---------------------&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> reg16 = <span class="regexp">/^(abc)&#123;3&#125;$/</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg16.<span class="title function_">test</span>(<span class="string">&#x27;abc&#x27;</span>), reg16.<span class="title function_">test</span>(<span class="string">&#x27;abcabcabc&#x27;</span>)); <span class="comment">// false true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(reg16.<span class="title function_">test</span>(<span class="string">&#x27;abccc&#x27;</span>)); <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//预定类</span></span><br><span class="line"><span class="comment">// \d 相当于 [0-9]; \D 相当于 [^0-9];</span></span><br><span class="line"><span class="comment">// \w 相当于 [A-Za-z0-9]; \W 相当于 [^A-Za-z0-9];</span></span><br><span class="line"><span class="comment">// \s 匹配空格(包括换行符、制表符、空格符等)，相等于[\t\r\n\v\f]; \S 相等于 [^\t\r\n\v\f]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 座机号码验证：全国座机号码 两种格式： 010-12345678 或者 0530-1234567</span></span><br><span class="line"><span class="comment">// 正则里面的  或者符号 |</span></span><br><span class="line"><span class="comment">// var reg17 = /^\d&#123;3&#125;-\d&#123;8&#125;|\d&#123;4&#125;-\d&#123;7&#125;$/;</span></span><br><span class="line"><span class="keyword">var</span> reg17 = <span class="regexp">/^\d&#123;3,4&#125;-\d&#123;7,8&#125;$/</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// replace()方法可以实现替换字符串操作，用来替换的参数可以是一个字符或是一个正则表达式</span></span><br><span class="line"><span class="comment">// stringObject.replace(regexp/substr, replacement)</span></span><br><span class="line"><span class="comment">// 第一个参数：被替换的字符串或者正则表达式</span></span><br><span class="line"><span class="comment">// 第二个参数：替换为的字符串； 返回值是一个替换完毕的新字符串</span></span><br><span class="line"><span class="comment">// /表达式/[switch] switch(也称为修饰符)按照什么样的模式来匹配，有三种值：</span></span><br><span class="line"><span class="comment">// g：全局匹配；i：忽略大小写；gi：全局匹配+忽略大小写</span></span><br><span class="line"><span class="keyword">var</span> text = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;textarea&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> btn = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;button&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> div = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;div&#x27;</span>);</span><br><span class="line">btn.<span class="title function_">addEventListener</span>(<span class="string">&#x27;click&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  div.<span class="property">innerHTML</span> = text.<span class="property">value</span>.<span class="title function_">replace</span>(<span class="regexp">/狗|挂机/g</span>, <span class="string">&#x27;**&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;请输入用户名&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>用户名<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">textarea</span> <span class="attr">name</span>=<span class="string">&quot;&quot;</span> <span class="attr">id</span>=<span class="string">&quot;message&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">textarea</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">button</span>&gt;</span>提交<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span></span><br></pre></td></tr></table></figure>


<h2 id="运算符-运算符"><a href="#运算符-运算符" class="headerlink" title="~~运算符 **运算符"></a>~~运算符 **运算符</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ~~运算符 **运算符</span></span><br><span class="line"><span class="comment">// ~是按位非，也就是按位取反，那么两个1~~就是2次取反，粗略的说是保持原值</span></span><br><span class="line"><span class="comment">// 但是~后面如果跟的值不是int类型，也会被强制转换为int类型</span></span><br><span class="line"><span class="comment">// 所以~~可以将字符串转换为数值，并且在有小数点的情况下取整</span></span><br><span class="line"><span class="comment">// 当然，是数值的情况下~~遇到小数点也是会转换int类型并取整</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(~<span class="string">&#x27;123&#x27;</span>, ~<span class="string">&#x27;123.4&#x27;</span>, ~<span class="number">123</span>, ~<span class="number">123.4</span>); <span class="comment">// 四次-124</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(~~<span class="string">&#x27;123&#x27;</span>, ~~<span class="string">&#x27;123.4&#x27;</span>, ~~<span class="number">123</span>, ~~<span class="number">123.4</span>); <span class="comment">// 四次123</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ~~后面如果跟Boolean类型、null和undefined也会转换成int类型变成数值</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(~~<span class="literal">true</span>, ~~<span class="literal">false</span>, ~~<span class="literal">null</span>, ~~<span class="literal">undefined</span>); <span class="comment">// 1 0 0 0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// **运算符作用与Math.pow一致</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">2</span> ** <span class="number">5</span>, <span class="title class_">Math</span>.<span class="title function_">pow</span>(<span class="number">2</span>, <span class="number">5</span>)); <span class="comment">// 都是幂运算：2的5次幂，结果为32</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="ES6-new-Map、new-Set"><a href="#ES6-new-Map、new-Set" class="headerlink" title="ES6 new Map、new Set"></a>ES6 new Map、new Set</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES6 New Map()的基础用法</span></span><br><span class="line"><span class="comment">// Map类型是键值对的有序列表，而键和值都可以是任意类型</span></span><br><span class="line"><span class="comment">// Set是一种叫做集合的数据结构，而Map是一种叫做字典的数据结构</span></span><br><span class="line"><span class="comment">// 集合：是一堆无序的，相关联的，且不重复的内存结构(元素)组成的组合</span></span><br><span class="line"><span class="comment">// 字典：是一些元素的集合。每个元素有一个称作key的域，不同元素的key各不相同</span></span><br><span class="line"><span class="comment">// Set集合是以[值,值]的形式存储元素</span></span><br><span class="line"><span class="comment">// Map字典是以[键,值]的形式存储元素</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 1、size属性返回Map结构的成员总数</span></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"><span class="keyword">const</span> fn = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;fn是一个函数&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;foo&#x27;</span>, <span class="literal">true</span>); <span class="comment">// 键是字符串</span></span><br><span class="line">map.<span class="title function_">set</span>(fn, <span class="literal">false</span>); <span class="comment">// 键是函数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>); <span class="comment">// 2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2、set()</span></span><br><span class="line"><span class="comment">// 设置键名key对应的键值为value，然后返回整个Map结构</span></span><br><span class="line"><span class="comment">// 如果可以已经有值，则键值会被更新，否则就新生成该键</span></span><br><span class="line"><span class="comment">// 同时返回的是当前的Map对象，可采用链式写法</span></span><br><span class="line">map.<span class="title function_">set</span>(<span class="number">1</span>, <span class="string">&#x27;a&#x27;</span>).<span class="title function_">set</span>(<span class="literal">undefined</span>, <span class="string">&#x27;undefined&#x27;</span>).<span class="title function_">set</span>(<span class="literal">null</span>, <span class="string">&#x27;null&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>); <span class="comment">// 5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3、get()</span></span><br><span class="line"><span class="comment">// 读取key对应的键值，如果找不到key，则返回undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(fn), map.<span class="title function_">get</span>(<span class="number">1</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4、has()</span></span><br><span class="line"><span class="comment">// 返回一个boolean，表示某个键是否在当前Map对象中</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">has</span>(<span class="number">1</span>), map.<span class="title function_">has</span>(<span class="number">2</span>)); <span class="comment">// true, false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 5、delete()</span></span><br><span class="line"><span class="comment">// 删除某个键，返回true，如果删除失败则返回false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">delete</span>(<span class="literal">null</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">delete</span>(<span class="literal">null</span>)); <span class="comment">// false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>); <span class="comment">// 4</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 6、clear()</span></span><br><span class="line"><span class="comment">// 清除所有成员，没有返回值</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">clear</span>()); <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>); <span class="comment">// 0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历</span></span><br><span class="line"><span class="comment">// keys() 返回键名的遍历器</span></span><br><span class="line"><span class="comment">// values() 返回键值的遍历器</span></span><br><span class="line"><span class="comment">// entries() 返回所有成员的遍历器</span></span><br><span class="line"><span class="comment">// forEach() 遍历Map的所有成员</span></span><br><span class="line"><span class="keyword">const</span> m = <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line">  [<span class="string">&#x27;F&#x27;</span>, <span class="string">&#x27;no&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;Y&#x27;</span>, <span class="string">&#x27;yes&#x27;</span>]</span><br><span class="line">]);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> key <span class="keyword">of</span> m.<span class="title function_">keys</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key); <span class="comment">// F Y</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> value <span class="keyword">of</span> m.<span class="title function_">values</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value); <span class="comment">// no yes</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> item <span class="keyword">of</span> m.<span class="title function_">entries</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item[<span class="number">0</span>], item[<span class="number">1</span>]); <span class="comment">// F no、 T yes</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// // 或者</span></span><br><span class="line"><span class="comment">// for (let [key, value] of map.entries()) &#123;</span></span><br><span class="line"><span class="comment">// console.log(key, value);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// // &quot;F&quot; &quot;no&quot; 、&quot;T&quot; &quot;yes&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// // 等同于使用map.entries()</span></span><br><span class="line"><span class="comment">// for (let [key, value] of map) &#123;</span></span><br><span class="line"><span class="comment">// console.log(key, value);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// // &quot;F&quot; &quot;no&quot; 、 &quot;T&quot; &quot;yes&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// map.forEach(function (value, key, map) &#123;</span></span><br><span class="line"><span class="comment">// console.log(key, value); // &quot;F&quot; &quot;no&quot; 、 &quot;T&quot; &quot;yes&quot;</span></span><br><span class="line"><span class="comment">// &#125;);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//Set数据结构 ES6提供了新的数据结构Set，它类似于数组，但是成员的值都是唯一的，没有重复的值</span></span><br><span class="line"><span class="comment">//Set本身是一个构造函数，用来生成Set数据结构</span></span><br><span class="line"><span class="comment">//Set函数可以接受一个数组作为参数，用来初始化</span></span><br><span class="line"><span class="keyword">const</span> ss1 = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss1.<span class="property">size</span>);</span><br><span class="line"><span class="keyword">const</span> ss2 = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss2.<span class="property">size</span>);</span><br><span class="line"><span class="keyword">const</span> ss3 = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss3); <span class="comment">//会把重复的值过滤掉</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss3.<span class="property">size</span>);</span><br><span class="line"><span class="keyword">const</span> ary10 = [...ss3];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ary10);</span><br><span class="line"><span class="comment">// Set实例方法</span></span><br><span class="line"><span class="comment">// add(value)：添加某个值，返回Set结构本身</span></span><br><span class="line"><span class="comment">// delete(value)：删除某个值，返回一个布尔值，表示删除是否成功</span></span><br><span class="line"><span class="comment">// has(value): 返回一个布尔值，表示该值是否为Set的成员</span></span><br><span class="line"><span class="comment">// clear()：清除所有成员，没有返回值</span></span><br><span class="line"><span class="keyword">const</span> ss4 = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"><span class="comment">// 向set结构中添加值，使用add方法</span></span><br><span class="line">ss4.<span class="title function_">add</span>(<span class="string">&#x27;a&#x27;</span>).<span class="title function_">add</span>(<span class="string">&#x27;b&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="property">size</span>); <span class="comment">// 2</span></span><br><span class="line"><span class="comment">// 从set结构中删除值，用到的方法是delete</span></span><br><span class="line"><span class="comment">// ss4.delete(&#x27;a&#x27;);</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="title function_">delete</span>(<span class="string">&#x27;a&#x27;</span>)); <span class="comment">// 当上面的 ss4.delete(&#x27;a&#x27;) 注释为true，否则反之</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="property">size</span>); <span class="comment">// 1</span></span><br><span class="line"><span class="comment">// 判断某个值是否是set数据结构中的成员，使用has</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="title function_">has</span>(<span class="string">&#x27;a&#x27;</span>)); <span class="comment">// false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="title function_">has</span>(<span class="string">&#x27;b&#x27;</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="comment">// 清空set数据结构中的值，使用clear方法</span></span><br><span class="line">ss4.<span class="title function_">clear</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(ss4.<span class="property">size</span>); <span class="comment">// 0</span></span><br><span class="line"><span class="comment">// 遍历 set结构的实例与数组一样，也拥有forEach方法，用于对每个成员执行某种操作，没有返回值</span></span><br><span class="line"><span class="keyword">const</span> ss5 = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>]);</span><br><span class="line">ss5.<span class="title function_">forEach</span>(<span class="function"><span class="params">value</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value); <span class="comment">// &#x27;a&#x27; &#x27;b&#x27; &#x27;c&#x27;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h2 id="js单链表"><a href="#js单链表" class="headerlink" title="js单链表"></a>js单链表</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">LinkListItem</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">value, next</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">value</span> = value;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">next</span> = next;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">add</span>(<span class="params">previous</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">next</span> = previous.<span class="property">next</span>;</span><br><span class="line">    previous.<span class="property">next</span> = <span class="variable language_">this</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">remove</span>(<span class="params">previous</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">next</span>) &#123;</span><br><span class="line">      previous.<span class="property">next</span> = <span class="variable language_">this</span>.<span class="property">next</span>;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">next</span> = <span class="literal">undefined</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">replace</span>(<span class="params">newItem</span>) &#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">LinkList</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">array</span>) &#123;</span><br><span class="line">    array.<span class="title function_">reverse</span>();</span><br><span class="line">    <span class="keyword">let</span> next;</span><br><span class="line">    array.<span class="title function_">forEach</span>(<span class="function">(<span class="params">element, i</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">const</span> newItem = <span class="keyword">new</span> <span class="title class_">LinkListItem</span>(element, next);</span><br><span class="line">      next = newItem;</span><br><span class="line">      <span class="keyword">if</span> (i === array.<span class="property">length</span> - <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">firstItem</span> = newItem;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">forEach</span>(<span class="params">callback</span>) &#123;</span><br><span class="line">    <span class="keyword">let</span> item = <span class="variable language_">this</span>.<span class="property">firstItem</span>;</span><br><span class="line">    <span class="keyword">let</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">do</span> &#123;</span><br><span class="line">      <span class="title function_">callback</span>(item.<span class="property">value</span>, i, <span class="variable language_">this</span>);</span><br><span class="line">      item = item.<span class="property">next</span>;</span><br><span class="line">      i++;</span><br><span class="line">    &#125; <span class="keyword">while</span> (item);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> test = <span class="keyword">new</span> <span class="title class_">LinkList</span>([<span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]);</span><br><span class="line">test.<span class="title function_">forEach</span>(<span class="function">(<span class="params">item, i, arr</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item, i, arr);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>


<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>


<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>
  </div>
  
  
    
    <div class='footer'>
       <!-- 参考资料、相关资料等 -->
      
       <!-- 相关文章 -->
      
      <!-- 版权声明组件 -->
      
      <!-- 打赏组件 -->
      
    </div>
  
  
    


  <div class='article-meta' id="bottom">
    <div class='new-meta-box'>
      
        
          <div class="new-meta-item date" itemprop="dateModified" datetime="2024-06-13T09:38:57+08:00">
  <a class='notlink'>
    <i class="fa-solid fa-edit fa-fw" aria-hidden="true"></i>
    <p>更新于：Jun 13, 2024</p>
  </a>
</div>

        
      
        
          
  
  <div class="new-meta-item meta-tags"><a class="tag" href="/tags/JavaScript/" rel="nofollow"><i class="fa-solid fa-hashtag fa-fw" aria-hidden="true"></i><p>JavaScript</p></a></div>
  <span hidden itemprop="keywords">JavaScript</span>


        
      
        
          
  <div class="new-meta-item share -mob-share-list">
  <div class="-mob-share-list share-body">
    
      
        <a class="-mob-share-qq" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://example.com/2023/12/22/JavaScript/&title=JavaScript - Knowledge&summary="
          
          >
          
            <img src="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/qq.png" class="lazyload" data-srcset="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/qq.png" srcset="">
          
        </a>
      
    
      
        <a class="-mob-share-qzone" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=http://example.com/2023/12/22/JavaScript/&title=JavaScript - Knowledge&summary="
          
          >
          
            <img src="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/qzone.png" class="lazyload" data-srcset="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/qzone.png" srcset="">
          
        </a>
      
    
      
        <a class="-mob-share-weibo" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="http://service.weibo.com/share/share.php?url=http://example.com/2023/12/22/JavaScript/&title=JavaScript - Knowledge&summary="
          
          >
          
            <img src="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/weibo.png" class="lazyload" data-srcset="https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/logo/128/weibo.png" srcset="">
          
        </a>
      
    
      
    
      
    
  </div>
</div>



        
      
    </div>
    <!-- Custom Files bottomMeta begin -->
    
    <!-- Custom Files bottomMeta end -->
  </div>


  
  

  
    <div class="prev-next">
      
        <a class='prev' href='/2023/12/26/vue3/'>
          <p class='title'><i class="fa-solid fa-chevron-left" aria-hidden="true"></i>vue3</p>
          <p class='content'>在Vue3中为图片请求添加请求头以下有两种方法的示例：方法一：使用axios库发送带请求头的图片请求方法二：自定义组件发送带请求头的图片请求
12345678910111213141516171...</p>
        </a>
      
      
        <a class='next' href='/2023/12/22/alova/'>
          <p class='title'>alova<i class="fa-solid fa-chevron-right" aria-hidden="true"></i></p>
          <p class='content'>在alovajs中无感刷新tokenhttps://juejin.cn/post/7311343224546738186?share_token=8229a43c-da25-4d90-a23f-...</p>
        </a>
      
    </div>
  
  <!-- Custom Files postEnd begin-->
  
  <!-- Custom Files postEnd end-->
</article>


  


  <article class="post white-box shadow floatable blur" id="comments">
    <span hidden>
      <meta itemprop="discussionUrl" content="/2023/12/22/JavaScript/index.html#comments">
    </span>
    <p ct><i class='fa-solid fa-comments'></i> 评论</p>
    

    <div id="layoutHelper-comments"></div>

  </article>






</div>
<aside id='l_side' itemscope itemtype="http://schema.org/WPSideBar">
  

  
    
    
      
    
  


<div class="widget-sticky pjax">

  
  


  <section class="widget toc-wrapper desktop mobile " id="toc-div" >
    
  <header>
    
      <i class="fa-solid fa-list fa-fw" aria-hidden="true"></i><span class='name'>本文目录</span>
    
  </header>


    <div class='content'>
        <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#localStorage"><span class="toc-text">localStorage</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%8A%82%E6%B5%81%E5%92%8C%E9%98%B2%E6%8A%96"><span class="toc-text">节流和防抖</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%95%E8%A1%8C%E4%BB%A3%E7%A0%81"><span class="toc-text">单行代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%97%AD%E5%8C%85"><span class="toc-text">闭包</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E5%9C%BA%E6%99%AF%E9%80%82%E5%90%88%E7%94%A8New-Map-%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E7%94%A8-Object"><span class="toc-text">什么场景适合用New Map()，而不是用 Object</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#call-apply-bind"><span class="toc-text">call apply bind</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9F%AF%E9%87%8C%E5%8C%96%E5%87%BD%E6%95%B0"><span class="toc-text">柯里化函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#arguments"><span class="toc-text">arguments</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B5%85%E6%8B%B7%E8%B4%9D-%E6%B7%B1%E6%8B%B7%E8%B4%9D"><span class="toc-text">浅拷贝 深拷贝</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84%E5%AE%9A%E4%B9%89%E6%96%B9%E5%BC%8F"><span class="toc-text">函数的定义方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E7%B1%BB%E5%92%8C%E7%94%9F%E6%88%90%E7%B1%BB"><span class="toc-text">创建类和生成类</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B"><span class="toc-text">基本类型和引用类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8B%E4%BB%B6"><span class="toc-text">事件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#javascript-%E4%B8%AD%EF%BC%9A%E2%80%99true%E2%80%99-true-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%94%E5%9B%9Efalse"><span class="toc-text">javascript 中：’true’ &#x3D;&#x3D; true; 为什么返回false</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E8%AE%A91-1%E7%AD%89%E4%BA%8E%E4%BB%BB%E4%BD%95%E6%95%B0"><span class="toc-text">我们可以让1+1等于任何数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#for-in-%E5%92%8C-for-of"><span class="toc-text">for in 和 for of</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B0%81%E8%A3%85replaceAll-%E6%96%B9%E6%B3%95"><span class="toc-text">封装replaceAll()方法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#toFixed%E4%B8%8D%E6%98%AF%E9%87%87%E7%94%A8%E4%BC%A0%E7%BB%9F%E6%84%8F%E4%B9%89%E4%B8%8A%E7%9A%84%E5%9B%9B%E8%88%8D%E4%BA%94%E5%85%A5%E6%B3%95%EF%BC%8C%E8%80%8C%E6%98%AF%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95"><span class="toc-text">toFixed不是采用传统意义上的四舍五入法，而是银行家算法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E5%92%8C%E5%8E%9F%E5%9E%8B"><span class="toc-text">构造函数和原型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="toc-text">正则表达式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E7%AE%97%E7%AC%A6-%E8%BF%90%E7%AE%97%E7%AC%A6"><span class="toc-text">~~运算符 **运算符</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ES6-new-Map%E3%80%81new-Set"><span class="toc-text">ES6 new Map、new Set</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#js%E5%8D%95%E9%93%BE%E8%A1%A8"><span class="toc-text">js单链表</span></a></li></ol>
    </div>
  </section>

  

</div>


<!-- 没有 pjax 占位会报错 万恶的 pjax -->

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <div class="pjax">
    <!-- pjax占位 -->
  </div>

  <!-- Custom Files side begin -->
  
  <!-- Custom Files side end -->
</aside>



          <!--此文件用来存放一些不方便取值的变量-->
<!--思路大概是将值藏到重加载的区域内-->

<pjax>
<script>
  window.pdata={}
  pdata.ispage=true;
  pdata.commentPath="";
  pdata.commentPlaceholder="";
  pdata.commentConfig={};
  //  see: /layout/_partial/scripts/_ctrl/coverCtrl.ejs
  
    // header
    var l_header=document.getElementById("l_header");
    
    l_header.classList.add("show");
    
    
      // cover
      var cover_wrapper=document.querySelector('#l_cover .cover-wrapper');
      var scroll_down=document.getElementById('scroll-down');
      cover_wrapper.id="none";
      cover_wrapper.style.display="none";
      scroll_down.style.display="none";
    
  
</script>
</pjax>
        </div>
        
  
  <footer class="footer clearfix"  itemscope itemtype="http://schema.org/WPFooter">
    <br><br>
    
      
        <div class="aplayer-container">
          


        </div>
      
    
      
        <br>
        <div class="social-wrapper" itemprop="about" itemscope itemtype="http://schema.org/Thing">
          
            
          
            
          
            
          
        </div>
      
    
      
        <div><p>Blog content follows the <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en">Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License</a></p>
</div>
      
    
      
        
          <div><p><span id="lc-sv">本站总访问量为 <span id='number'><i class="fa-solid fa-loader fa-spin fa-fw" aria-hidden="true"></i></span> 次</span> <span id="lc-uv">访客数为 <span id='number'><i class="fa-solid fa-loader fa-spin fa-fw" aria-hidden="true"></i></span> 人</span></p>
</div>
        
      
    
      
        Use
        <a href="https://github.com/volantis-x/hexo-theme-volantis/#5.8.0" target="_blank" class="codename">Volantis</a>
        as theme
      
    
      
        <div class='copyright'>
        <p><a href="/">Copyright © since 2017 XXX</a></p>

        </div>
      
    
    <!-- Custom Files footer begin-->
    
    <!-- Custom Files footer end-->
  </footer>


        <a id="s-top" class="fa-solid fa-arrow-up fa-fw" href="/" onclick="return false;" title="top"></a>
      </div>
    </div>
    <div>
      <script>
  /******************** volantis.dom ********************************/
  // 页面选择器 将dom对象缓存起来 see: /source/js/app.js etc.
  volantis.dom.bodyAnchor = volantis.dom.$(document.getElementById("safearea")); // 页面主体
  volantis.dom.topBtn = volantis.dom.$(document.getElementById('s-top')); // 向上
  volantis.dom.wrapper = volantis.dom.$(document.getElementById('wrapper')); // 整个导航栏
  volantis.dom.coverAnchor = volantis.dom.$(document.querySelector('#l_cover .cover-wrapper')); // 1个
  volantis.dom.switcher = volantis.dom.$(document.querySelector('#l_header .switcher .s-search')); // 搜索按钮   移动端 1个
  volantis.dom.header = volantis.dom.$(document.getElementById('l_header')); // 移动端导航栏
  volantis.dom.search = volantis.dom.$(document.querySelector('#l_header .m_search')); // 搜索框 桌面端 移动端 1个
  volantis.dom.mPhoneList = volantis.dom.$(document.querySelectorAll('#l_header .m-phone .list-v')); //  手机端 子菜单 多个
</script>

<script>
  
  volantis.css("https://unpkg.com/volantis-static@0.0.1654736714924/libs/@fortawesome/fontawesome-free/css/all.min.css");
  
  
  
</script>

<!-- required -->


<!-- internal -->

<script src="/js/app.js"></script>






<!-- rightmenu要在darkmode之前（ToggleButton） darkmode要在comments之前（volantis.dark.push）-->



<script>
  function loadIssuesJS() {
    
      const sites_api = document.getElementById('sites-api');
      if (sites_api != undefined && typeof SitesJS === 'undefined') {
        volantis.js("/js/plugins/tags/sites.js")
      }
    
    
      const friends_api = document.getElementById('friends-api');
      if (friends_api != undefined && typeof FriendsJS === 'undefined') {
        volantis.js("/js/plugins/tags/friends.js")
      }
    
    
      const contributors_api = document.getElementById('contributors-api');
      if (contributors_api != undefined && typeof ContributorsJS === 'undefined') {
        volantis.js("/js/plugins/tags/contributors.js")
      }
    
  };
  loadIssuesJS()
  volantis.pjax.push(()=>{
    loadIssuesJS();
  })

</script>




  <script defer src="https://unpkg.com/volantis-static@0.0.1654736714924/libs/vanilla-lazyload/dist/lazyload.min.js"></script>
<script>
  // https://www.npmjs.com/package/vanilla-lazyload
  // Set the options globally
  // to make LazyLoad self-initialize
  window.lazyLoadOptions = {
    elements_selector: ".lazyload",
    threshold: 0
  };
  // Listen to the initialization event
  // and get the instance of LazyLoad
  window.addEventListener(
    "LazyLoad::Initialized",
    function (event) {
      window.lazyLoadInstance = event.detail.instance;
    },
    false
  );
  document.addEventListener('DOMContentLoaded', function () {
    lazyLoadInstance.update();
  });
  document.addEventListener('pjax:complete', function () {
    lazyLoadInstance.update();
  });
</script>




  

<script>
  window.FPConfig = {
	delay: 0,
	ignoreKeywords: ["#"],
	maxRPS: 6,
	hoverDelay: 0
  };
</script>
<script defer src="https://unpkg.com/volantis-static@0.0.1654736714924/libs/flying-pages/flying-pages.min.js"></script>









      <script>
  volantis.layoutHelper("comments",`<div id="giscus_container"></div>`)

  volantis.giscus = {};

  function check_giscus() {
    if (volantis.dark.mode === "dark") {
      volantis.giscus.Theme = 'dark';
    } else {
      volantis.giscus.Theme = 'light';
    }

    return document.getElementById("giscus_container");
  }

  function pjax_giscus() {
    const HEAD = check_giscus();
    if (!HEAD) return;
    let cfg = Object.assign({"theme":{"light":"light","dark":"dark"}},pdata.commentConfig)
    const script = document.createElement('script');
    script.setAttribute('src', 'https://giscus.app/client.js');
    Object.keys(cfg).forEach(k=>{
      if (k != "theme") {
        script.setAttribute('data-'+k, cfg[k]);
      }
    })
    script.setAttribute('data-theme', volantis.giscus.Theme);
    script.setAttribute('crossorigin', "anonymous");
    HEAD.appendChild(script);
  }

  function dark_giscus() {
    const HEAD = check_giscus();
    if (!HEAD) return;

    const message = {
      setConfig: {
        theme: volantis.giscus.Theme
      }
    };
    const giscusIframe = document.querySelector('iframe.giscus-frame');
    giscusIframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
  }
  pjax_giscus();
  volantis.pjax.push(pjax_giscus);
  volantis.dark.push(dark_giscus);
</script>

    





<!-- optional -->

  <script>
  const SearchServiceDataPathRoot = ("/" || "/").endsWith("/") ?
    "/" || "/" :
    "//" || "/";
  const SearchServiceDataPath = SearchServiceDataPathRoot + "content.json";

  function loadSearchScript() {
    // see: layout/_partial/scripts/_ctrl/cdnCtrl.ejs
    return volantis.js("/js/search/hexo.js");
  }

  function loadSearchService() {
    loadSearchScript();
    document.querySelectorAll(".input.u-search-input").forEach((e) => {
      e.removeEventListener("focus", loadSearchService, false);
    });

    document.querySelectorAll(".u-search-form").forEach((e) => {
      e.addEventListener("submit", (event) => {
        event.preventDefault();
      }, false);
    });
  }

  // 打开并搜索 字符串 s
  function OpenSearch(s) {
    if (typeof SearchService === 'undefined')
      loadSearchScript().then(() => {
        SearchService.setQueryText(s);
        SearchService.search();
      });
    else {
      SearchService.setQueryText(s);
      SearchService.search();
    }
  }

  // 访问含有 ?s=xxx  的链接时打开搜索 // 与搜索引擎 structured data 相关: /scripts/helpers/structured-data/lib/config.js
  if (window.location.search && /^\?s=/g.test(window.location.search)) {
    let queryText = decodeURI(window.location.search)
      .replace(/\ /g, "-")
      .replace(/^\?s=/g, "");
    OpenSearch(queryText);
  }

  // 搜索输入框获取焦点时加载搜索
  document.querySelectorAll(".input.u-search-input").forEach((e) => {
    e.addEventListener("focus", loadSearchService, false);
  });
</script>







  <script>



  function pjax_highlightjs_copyCode(){
    if (!(document.querySelector(".highlight .code pre") ||
      document.querySelector(".article pre code"))) {
      return;
    }
    VolantisApp.utilCopyCode(".highlight .code pre, .article pre code")
  }
  volantis.requestAnimationFrame(pjax_highlightjs_copyCode)
  volantis.pjax.push(pjax_highlightjs_copyCode)

</script>












  <script>
  function load_swiper() {
    if (!document.querySelectorAll(".swiper-container")[0]) return;
    volantis.css("https://unpkg.com/volantis-static@0.0.1654736714924/libs/swiper/swiper-bundle.min.css");
    volantis.js("https://unpkg.com/volantis-static@0.0.1654736714924/libs/swiper/swiper-bundle.min.js").then(() => {
      pjax_swiper();
    });
  }

  load_swiper();

  function pjax_swiper() {
    volantis.swiper = new Swiper('.swiper-container', {
      slidesPerView: 'auto',
      spaceBetween: 8,
      centeredSlides: true,
      loop: true,
      pagination: {
        el: '.swiper-pagination',
        clickable: true,
      },
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
    });
  }

  volantis.pjax.push(() => {
    if (!document.querySelectorAll(".swiper-container")[0]) return;
    if (typeof volantis.swiper === "undefined") {
      load_swiper();
    } else {
      pjax_swiper();
    }
  });
</script>


<!-- pjax 标签必须存在于所有页面 否则 pjax error -->
<pjax>

</pjax>

<script>
  function listennSidebarTOC() {
    const navItems = document.querySelectorAll(".toc li");
    if (!navItems.length) return;
    let targets = []
    const sections = [...navItems].map((element) => {
      const link = element.querySelector(".toc-link");
      const target = document.getElementById(
        decodeURI(link.getAttribute("href")).replace("#", "")
      );
      targets.push(target)
      // 解除 a 标签 href 的 锚点定位, a 标签 href 的 锚点定位 会随机启用?? 产生错位???
      link.setAttribute("onclick","return false;")
      link.setAttribute("toc-action","toc-"+decodeURI(link.getAttribute("href")).replace("#", ""))
      link.setAttribute("href","/")
      // 配置 点击 触发新的锚点定位
      link.addEventListener("click", (event) => {
        event.preventDefault();
        // 这里的 addTop 是通过错位使得 toc 自动展开.
        volantis.scroll.to(target,{addTop: 5, observer:true})
        // Anchor id
        history.pushState(null, document.title, "#" + target.id);
      });
      return target;
    });

    function activateNavByIndex(target) {
      if (target.classList.contains("active-current")) return;

      document.querySelectorAll(".toc .active").forEach((element) => {
        element.classList.remove("active", "active-current");
      });
      target.classList.add("active", "active-current");
      let parent = target.parentNode;
      while (!parent.matches(".toc")) {
        if (parent.matches("li")) parent.classList.add("active");
        parent = parent.parentNode;
      }
    }

    // 方案一：
    volantis.activateNavIndex=0
    activateNavByIndex(navItems[volantis.activateNavIndex])
    volantis.scroll.push(()=>{
      if (targets[0].getBoundingClientRect().top >= 0) {
        volantis.activateNavIndex = 0
      }else if (targets[targets.length-1].getBoundingClientRect().top < 0) {
        volantis.activateNavIndex = targets.length-1
      } else {
        for (let index = 0; index < targets.length; index++) {
          const target0 = targets[index];
          const target1 = targets[(index+1)%targets.length];
          if (target0.getBoundingClientRect().top < 0&&target1.getBoundingClientRect().top >= 0) {
            volantis.activateNavIndex=index
            break;
          }
        }
      }
      activateNavByIndex(navItems[volantis.activateNavIndex])
    })

    // 方案二：
    // IntersectionObserver 不是完美精确到像素级别 也不是低延时性的
    // function findIndex(entries) {
    //   let index = 0;
    //   let entry = entries[index];
    //   if (entry.boundingClientRect.top > 0) {
    //     index = sections.indexOf(entry.target);
    //     return index === 0 ? 0 : index - 1;
    //   }
    //   for (; index < entries.length; index++) {
    //     if (entries[index].boundingClientRect.top <= 0) {
    //       entry = entries[index];
    //     } else {
    //       return sections.indexOf(entry.target);
    //     }
    //   }
    //   return sections.indexOf(entry.target);
    // }
    // function createIntersectionObserver(marginTop) {
    //   marginTop = Math.floor(marginTop + 10000);
    //   let intersectionObserver = new IntersectionObserver(
    //     (entries, observe) => {
    //       let scrollHeight = document.documentElement.scrollHeight;
    //       if (scrollHeight > marginTop) {
    //         observe.disconnect();
    //         createIntersectionObserver(scrollHeight);
    //         return;
    //       }
    //       let index = findIndex(entries);
    //       activateNavByIndex(navItems[index]);
    //     }, {
    //       rootMargin: marginTop + "px 0px -100% 0px",
    //       threshold: 0,
    //     }
    //   );
    //   sections.forEach((element) => {
    //     element && intersectionObserver.observe(element);
    //   });
    // }
    // createIntersectionObserver(document.documentElement.scrollHeight);
  }

  document.addEventListener("DOMContentLoaded", ()=>{
    volantis.requestAnimationFrame(listennSidebarTOC)
  });
  document.addEventListener("pjax:success", ()=>{
    volantis.requestAnimationFrame(listennSidebarTOC)
  });
</script>



<script>
  document.onreadystatechange = function () {
    if (document.readyState == 'complete') {
      // 页面加载完毕 样式加载失败，或是当前网速慢，或是开启了省流模式
      const { saveData, effectiveType } = navigator.connection || navigator.mozConnection || navigator.webkitConnection || {}
      if (getComputedStyle(document.querySelector("#safearea"), null)["display"] == "none" || saveData || /2g/.test(effectiveType)) {
        document.querySelectorAll(".reveal").forEach(function (e) {
          e.style["opacity"] = "1";
        });
        document.querySelector("#safearea").style["display"] = "block";
      }
    }
  }
</script>


  <script type="application/ld+json">[{"@context":"http://schema.org","@type":"Organization","name":"Knowledge","url":"http://example.com/","logo":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png","width":192,"height":192}},{"@context":"http://schema.org","@type":"Person","name":"weijt","image":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png"},"url":"http://example.com/","sameAs":["https://github.com/volantis-x"],"description":"html css node vue node"},{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"http://example.com/","name":"Knowledge"}},{"@type":"ListItem","position":3,"item":{"@id":"http://example.com/2023/12/22/JavaScript/","name":"JavaScript"}}]},{"@context":"http://schema.org","@type":"WebSite","name":"Knowledge","url":"http://example.com/","keywords":"html css node vue node","description":"html css node vue node","author":{"@type":"Person","name":"weijt","image":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png"},"url":"http://example.com/","description":"html css node vue node"},"publisher":{"@type":"Organization","name":"Knowledge","url":"http://example.com/","logo":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png","width":192,"height":192}},"potentialAction":{"@type":"SearchAction","name":"Site Search","target":{"@type":"EntryPoint","urlTemplate":"http://example.com?s={search_term_string}"},"query-input":"required name=search_term_string"}},{"@context":"http://schema.org","@type":"BlogPosting","headline":"JavaScript","description":"html css node vue node","inLanguage":"en","mainEntityOfPage":{"@type":"WebPage","@id":"http://example.com/2023/12/22/JavaScript/"},"author":{"@type":"Person","name":"weijt","image":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png"},"url":"http://example.com/"},"publisher":{"@type":"Organization","name":"Knowledge","logo":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png","width":192,"height":192}},"url":"http://example.com/2023/12/22/JavaScript/","wordCount":0,"datePublished":"2023-12-22T03:11:03.467Z","dateModified":"2024-06-13T01:38:57.695Z","keywords":"JavaScript","image":{"@type":"ImageObject","url":"https://unpkg.com/volantis-static@0.0.1654736714924/media/org.volantis/blog/favicon/android-chrome-192x192.png","width":192,"height":192}}]</script>



      
        <!--
  pjax重载区域接口：
  1.  <pjax></pjax> 标签 pjax 标签必须存在于所有页面 否则 pjax error
  2.  script[data-pjax]
  3.  .pjax-reload script
  4.  .pjax
-->



<script src="https://unpkg.com/volantis-static@0.0.1654736714924/libs/pjax/pjax.min.js"></script>


<script>
    var pjax;
    document.addEventListener('DOMContentLoaded', function () {
      pjax = new Pjax({
        elements: 'a[href]:not([href^="#"]):not([href="javascript:void(0)"]):not([pjax-fancybox]):not([onclick="return false;"]):not([onclick="return!1"]):not([target="_blank"]):not([target="view_window"]):not([href$=".xml"])',
        selectors: [
          "head title",
          "head meta[name=keywords]",
          "head meta[name=description]",
          
          "#l_main",
          "#pjax-header-nav-list",
          ".pjax",
          "pjax", // <pjax></pjax> 标签
          "script[data-pjax], .pjax-reload script" // script标签添加data-pjax 或 script标签外层添加.pjax-reload 的script代码段重载
        ],
        cacheBust: false,   // url 地址追加时间戳，用以避免浏览器缓存
        timeout: 5000,
        
      });
    });

    document.addEventListener('pjax:send', function (e) {
      //window.stop(); // 相当于点击了浏览器的停止按钮

      try {
        var currentUrl = window.location.pathname;
        var targetUrl = e.triggerElement.href;
        var banUrl = [""];
        if (banUrl[0] != "") {
          banUrl.forEach(item => {
            if(currentUrl.indexOf(item) != -1 || targetUrl.indexOf(item) != -1) {
              window.location.href = targetUrl;
            }
          });
        }
      } catch (error) {}

      // 使用 volantis.pjax.send 方法传入pjax:send回调函数 参见layout/_partial/scripts/global.ejs
      volantis.pjax.method.send.start();
    });

    document.addEventListener('pjax:complete', function () {
      // 使用 volantis.pjax.push 方法传入重载函数 参见layout/_partial/scripts/global.ejs
      volantis.pjax.method.complete.start();
    });

    document.addEventListener('pjax:error', function (e) {
      if(volantis.debug) {
        console.error(e);
        console.log('pjax error: \n' + JSON.stringify(e));
      }else{
        // 使用 volantis.pjax.error 方法传入pjax:error回调函数 参见layout/_partial/scripts/global.ejs
        volantis.pjax.method.error.start();
        window.location.href = e.triggerElement.href;
      }
    });
</script>

      
    </div>
    <!-- import body_end begin-->
    <!-- import body_end end-->
    <!-- Custom Files bodyEnd begin-->
    
    <!-- Custom Files bodyEnd end-->
    <!-- front-matter body_end begin -->
    <!-- front-matter body_end end -->
  </body>
</html>
